RESTinio
Loading...
Searching...
No Matches
sendfile_operation_default.ipp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#include <cstdio>
10
11namespace restinio
12{
13
14namespace impl
15{
16
17//
18// sendfile_operation_runner_t
19//
20
22template < typename Socket >
24 : public sendfile_operation_runner_base_t< Socket >
25{
26 public:
28
33
34 // Reuse construstors from base.
35 using base_type_t::base_type_t;
36
37
38 virtual void
39 start() override
40 {
41 const auto n =
42 std::fseek(
44 //eao197: suppress warning from a compiler if restinio::file_offset_t
45 //is not long.
46 static_cast<long>(this->m_next_write_offset),
47 SEEK_SET );
48
49 if( 0 == n )
50 {
51 this->init_next_write();
52 }
53 else
54 {
56 make_error_code( std::ferror( this->m_file_descriptor ) ),
57 this->m_transfered_size );
58 return;
59 }
60 }
61
66 void
68 {
69 const auto desired_size =
70 std::min< file_size_t >( this->m_remained_size, this->m_chunk_size );
71
72 const auto n =
73 std::fread(
74 this->m_buffer.get(),
75 1,
77 this->m_file_descriptor );
78
79 if( desired_size != n )
80 {
82 make_error_code( std::ferror( this->m_file_descriptor ) ),
83 this->m_transfered_size );
84 }
85 else
86 {
87 // If asio_ns::async_write fails we'll call m_after_sendfile_cb.
88 try
89 {
90 asio_ns::async_write(
91 this->m_socket,
92 asio_ns::const_buffer{
93 this->m_buffer.get(),
94 static_cast< std::size_t >( desired_size ) },
95 asio_ns::bind_executor(
96 this->m_executor,
98 }
99 catch( ... )
100 {
104 this->m_transfered_size );
105 }
106 }
107 }
108
109 private:
110 std::unique_ptr< char[] > m_buffer{ new char [ this->m_chunk_size ] };
111
113 auto
115 {
116 return [ this, ctx = this->shared_from_this() ]
117 // NOTE: this lambda is noexcept since v.0.6.0.
118 ( const asio_ns::error_code & ec, std::size_t written ) noexcept
119 {
120 if( !ec )
121 {
122 this->m_remained_size -= written;
123 this->m_transfered_size += written;
124 if( 0 == this->m_remained_size )
125 {
126 this->m_after_sendfile_cb( ec, this->m_transfered_size );
127 }
128 else
129 {
130 this->init_next_write();
131 }
132 }
133 else
134 {
135 this->m_after_sendfile_cb( ec, this->m_transfered_size );
136 }
137 };
138 }
139};
140
141} /* namespace impl */
142
143} /* namespace restinio */
144
A base runner of sendfile operation (keeps all the data).
auto make_async_write_handler() noexcept
Helper method for making a lambda for async_write completion handler.
sendfile_operation_runner_t(const sendfile_operation_runner_t &)=delete
sendfile_operation_runner_t & operator=(const sendfile_operation_runner_t &)=delete
sendfile_operation_runner_t(sendfile_operation_runner_t &&)=delete
auto make_error_code(const Error_Type &e) noexcept
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
@ async_write_call_failed
A call to async_write failed. The corresponding write operation wasn't done.
asio_ns::error_code make_asio_compaible_error(asio_convertible_error_t err) noexcept
Make restinio error_code compatible with asio_ns::error_code.