13 #include <restinio/asio_include.hpp> 15 #include <restinio/buffers.hpp> 16 #include <restinio/optional.hpp> 17 #include <restinio/variant.hpp> 18 #include <restinio/impl/sendfile_operation.hpp> 84 using len_t =
decltype( asio_ns::detail::max_iov_len );
85 return std::min< len_t >( asio_ns::detail::max_iov_len, 64 );
95 m_asio_bufs.reserve( max_iov_len() );
108 const asio_bufs_container_t & asio_bufs,
110 std::size_t total_size )
noexcept 143 sendfile_t & sendfile,
144 sendfile_operation_shared_ptr_t & sendfile_operation )
noexcept 162 template<
typename Socket,
typename After_Write_CB >
165 asio_ns::executor executor,
167 After_Write_CB after_sendfile_cb )
174 throw exception_t{
"invalid file descriptor in sendfile operation." };
192 assert( m_sendfile->is_valid() );
194 return m_sendfile->timelimit();
201 m_sendfile_operation->reset();
205 auto size()
const noexcept {
return m_sendfile->size(); }
228 bool transmitting()
const noexcept {
return static_cast<
bool >( m_current_wg ); }
234 m_current_wg = std::move( next_wg );
248 assert( m_current_wg );
250 solid_write_operation_variant_t result{ none_write_operation_t{} };
252 if( m_next_writable_item_index < m_current_wg->items_count() )
255 const auto next_wi_type =
256 m_current_wg->items()[ m_next_writable_item_index ].write_type();
258 if( writable_item_type_t::trivial_write_operation == next_wi_type )
261 result = prepare_trivial_buffers_wo();
266 assert( writable_item_type_t::file_write_operation == next_wi_type );
267 result = prepare_sendfile_wo();
278 assert( m_current_wg );
280 invoke_after_write_notificator_if_necessary( ec );
281 m_current_wg.reset();
282 m_sendfile_operation.reset();
289 assert( m_current_wg );
291 invoke_after_write_notificator_if_necessary( asio_ns::error_code{} );
300 m_current_wg.reset();
301 m_next_writable_item_index = 0;
310 m_current_wg->invoke_after_write_notificator_if_exists( ec );
312 catch(
const std::exception & ex )
321 fmt::format(
"after write callback failed: {}", ex.what() ) };
331 const auto & items = m_current_wg->items();
332 std::size_t total_size{ 0 };
334 for( ;m_next_writable_item_index < items.size() &&
335 writable_item_type_t::trivial_write_operation ==
336 items[ m_next_writable_item_index ].write_type() &&
337 max_iov_len() > m_asio_bufs.size();
338 ++m_next_writable_item_index )
340 const auto & item = items[ m_next_writable_item_index ];
341 m_asio_bufs.emplace_back( item.buf() );
342 total_size += item.size();
345 assert( !m_asio_bufs.empty() );
346 return trivial_write_operation_t{ m_asio_bufs, total_size };
354 m_current_wg->items()[ m_next_writable_item_index++ ].sendfile_operation();
356 return file_write_operation_t{ sf, m_sendfile_operation };
file_write_operation_t & operator=(const file_write_operation_t &)=default
auto size() const noexcept
The size of data within this operation.
file_write_operation_t(file_write_operation_t &&)=default
Helper class for writting response data.
bool transmitting() const noexcept
Check if data is trunsmitting now.
file_write_operation_t(sendfile_t &sendfile, sendfile_operation_shared_ptr_t &sendfile_operation) noexcept
void start_next_write_group(optional_t< write_group_t > next_wg) noexcept
Start handlong next write group.
Write operaton using sendfile.
trivial_write_operation_t & operator=(trivial_write_operation_t &&)=default
file_write_operation_t(const file_write_operation_t &)=default
const std::vector< asio_ns::const_buffer > & get_trivial_bufs() const noexcept
Get buffer "iovec" for performing gather write.
void fail_write_group(const asio_ns::error_code &ec)
Handle current group write process failed.
trivial_write_operation_t prepare_trivial_buffers_wo()
Prepare write operation for trivial buffers.
sendfile_t * m_sendfile
A pointer to sendfile.
static constexpr auto max_iov_len() noexcept
Get the maximum number of buffers that can be written with gather write operation.
asio_bufs_container_t m_asio_bufs
Asio buffers storage.
const asio_bufs_container_t * m_asio_bufs
auto size() const noexcept
Get the size of sendfile operation.
void finish_write_group()
Finish writing group normally.
file_write_operation_t prepare_sendfile_wo()
Prepare write operation for sendfile.
trivial_write_operation_t(trivial_write_operation_t &&)=default
void invoke_after_write_notificator_if_necessary(const asio_ns::error_code &ec)
Execute notification callback if necessary.
void reset()
Reset write operation context.
trivial_write_operation_t(const trivial_write_operation_t &)=default
trivial_write_operation_t(const asio_bufs_container_t &asio_bufs, std::size_t total_size) noexcept
sendfile_operation_shared_ptr_t m_sendfile_operation
Sendfile operation storage context.
optional_t< write_group_t > m_current_wg
Real buffers with data.
file_write_operation_t & operator=(file_write_operation_t &&)=default
std::size_t m_next_writable_item_index
Keeps track of the next writable item stored in m_current_wg.
sendfile_operation_shared_ptr_t * m_sendfile_operation
A curernt sendfile operation.
auto timelimit() const noexcept
Get the timelimit on this sendfile operation.
solid_write_operation_variant_t extract_next_write_operation()
et an object with next write operation to perform.
void start_sendfile_operation(asio_ns::executor executor, Socket &socket, After_Write_CB after_sendfile_cb)
Start a sendfile operation.
void reset_write_group()
Reset the write group and associated context.
write_group_output_ctx_t()
Contruct an object.
trivial_write_operation_t & operator=(const trivial_write_operation_t &)=default
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...