9 #if defined(RESTINIO_ASIO_HAS_WINDOWS_OVERLAPPED_PTR) 24 template <
typename Socket >
25 class sendfile_operation_runner_t final
26 :
public sendfile_operation_runner_base_t< Socket >
29 using base_type_t = sendfile_operation_runner_base_t< Socket >;
31 sendfile_operation_runner_t(
const sendfile_operation_runner_t & ) =
delete;
32 sendfile_operation_runner_t( sendfile_operation_runner_t && ) =
delete;
33 sendfile_operation_runner_t & operator = (
const sendfile_operation_runner_t & ) =
delete;
34 sendfile_operation_runner_t & operator = ( sendfile_operation_runner_t && ) =
delete;
36 sendfile_operation_runner_t(
38 asio_ns::executor executor,
40 after_sendfile_cb_t after_sendfile_cb )
41 : base_type_t{ sf, std::move( executor), socket, std::move( after_sendfile_cb ) }
48 takeaway_file_descriptor(sf).release();
54 init_next_read_some_from_file();
58 init_next_read_some_from_file()
60 const auto desired_size =
61 std::min< file_size_t >(
this->m_remained_size,
this->m_chunk_size );
63 this->m_file_handle.async_read_some_at(
64 this->m_next_write_offset,
67 static_cast< std::size_t >( desired_size ) ),
68 asio_ns::bind_executor(
70 [
this, ctx =
this->shared_from_this() ]
71 (
const asio_ns::error_code & ec, std::size_t len ){
73 if( ec || 0 ==
this->m_remained_size )
75 this->m_after_sendfile_cb( ec,
this->m_transfered_size );
80 init_next_write( len );
83 this->m_after_sendfile_cb(
84 make_error_code( asio_ec::eof ),
85 this->m_transfered_size );
90 this->m_after_sendfile_cb( ec,
this->m_transfered_size );
96 init_next_write( std::size_t len )
100 asio_ns::const_buffer{
101 this->m_buffer.get(),
102 static_cast< std::size_t >( len ) },
103 asio_ns::bind_executor(
105 [
this, ctx =
this->shared_from_this() ]
106 (
const asio_ns::error_code & ec, std::size_t written ){
110 this->m_remained_size -= written;
111 this->m_transfered_size += written;
112 this->m_next_write_offset += written;
114 if( 0 ==
this->m_remained_size )
116 this->m_after_sendfile_cb( ec,
this->m_transfered_size );
120 this->init_next_read_some_from_file();
125 this->m_after_sendfile_cb( ec,
this->m_transfered_size );
132 std::unique_ptr<
char[] > m_buffer{
new char [
this->m_chunk_size ] };
133 asio_ns::windows::random_access_handle
134 m_file_handle{
this->m_socket.get_executor().context(),
this->m_file_descriptor };
139 class sendfile_operation_runner_t < asio_ns::ip::tcp::socket > final
140 :
public sendfile_operation_runner_base_t< asio_ns::ip::tcp::socket >
143 using base_type_t = sendfile_operation_runner_base_t< asio_ns::ip::tcp::socket >;
145 sendfile_operation_runner_t(
const sendfile_operation_runner_t & ) =
delete;
146 sendfile_operation_runner_t( sendfile_operation_runner_t && ) =
delete;
147 sendfile_operation_runner_t & operator = (
const sendfile_operation_runner_t & ) =
delete;
148 sendfile_operation_runner_t & operator = ( sendfile_operation_runner_t && ) =
delete;
150 sendfile_operation_runner_t(
152 asio_ns::executor executor,
153 asio_ns::ip::tcp::socket & socket,
154 after_sendfile_cb_t after_sendfile_cb )
155 : base_type_t{ sf, std::move( executor), socket, std::move( after_sendfile_cb ) }
162 takeaway_file_descriptor(sf).release();
175 asio_ns::windows::overlapped_ptr overlapped{
176 m_socket.get_executor().context(),
177 asio_ns::bind_executor(
179 [
this, ctx = shared_from_this() ]
180 (
const asio_ns::error_code & ec, std::size_t written ){
183 m_remained_size -= written;
184 m_transfered_size += written;
185 m_next_write_offset += written;
187 if( 0 == m_remained_size )
189 m_after_sendfile_cb( ec, m_transfered_size );
198 m_after_sendfile_cb( ec, m_transfered_size );
203 overlapped.get()->Offset =
204 static_cast< DWORD >( m_next_write_offset & 0xFFFFFFFFULL );
205 overlapped.get()->OffsetHigh =
206 static_cast< DWORD >( (m_next_write_offset>>32) & 0xFFFFFFFFULL );
209 const auto desired_size =
210 std::min< file_size_t >(
this->m_remained_size,
this->m_chunk_size );
215 m_socket.native_handle(),
216 m_file_handle.native_handle(),
217 static_cast< DWORD >( desired_size ),
223 DWORD last_error = ::GetLastError();
226 if( !ok && last_error != ERROR_IO_PENDING )
231 overlapped.complete( make_error_code( last_error ) , 0 );
237 overlapped.release();
242 std::unique_ptr<
char[] > m_buffer{
new char [ m_chunk_size ] };
243 asio_ns::windows::random_access_handle
244 m_file_handle{ m_socket.get_executor().context(), m_file_descriptor };