11 #include <restinio/asio_include.hpp> 13 #include <restinio/buffers.hpp> 14 #include <restinio/impl/sendfile_operation.hpp> 16 #include <restinio/compiler_features.hpp> 86 using len_t =
decltype( asio_ns::detail::max_iov_len );
87 return static_cast< asio_bufs_container_t::size_type >(
88 std::min< len_t >( asio_ns::detail::max_iov_len, 64 ) );
98 m_asio_bufs.reserve( max_iov_len() );
111 const asio_bufs_container_t & asio_bufs,
113 std::size_t total_size )
noexcept 146 sendfile_t & sendfile,
147 sendfile_operation_shared_ptr_t & sendfile_operation )
noexcept 165 template<
typename Socket,
typename After_Write_CB >
168 default_asio_executor executor,
170 After_Write_CB after_sendfile_cb )
177 throw exception_t{
"invalid file descriptor in sendfile operation." };
195 assert( m_sendfile->is_valid() );
197 return m_sendfile->timelimit();
208 RESTINIO_ENSURE_NOEXCEPT_CALL( m_sendfile_operation->reset() );
212 auto size()
const noexcept {
return m_sendfile->size(); }
235 bool transmitting()
const noexcept {
return static_cast<
bool >( m_current_wg ); }
241 m_current_wg = std::move( next_wg );
255 assert( m_current_wg );
257 solid_write_operation_variant_t result{ none_write_operation_t{} };
259 if( m_next_writable_item_index < m_current_wg->items_count() )
262 const auto next_wi_type =
263 m_current_wg->items()[ m_next_writable_item_index ].write_type();
265 if( writable_item_type_t::trivial_write_operation == next_wi_type )
268 result = prepare_trivial_buffers_wo();
273 assert( writable_item_type_t::file_write_operation == next_wi_type );
274 result = prepare_sendfile_wo();
285 assert( m_current_wg );
287 invoke_after_write_notificator_if_necessary( ec );
288 m_current_wg.reset();
289 m_sendfile_operation.reset();
296 assert( m_current_wg );
298 invoke_after_write_notificator_if_necessary( asio_ns::error_code{} );
307 m_current_wg.reset();
308 m_next_writable_item_index = 0;
317 m_current_wg->invoke_after_write_notificator_if_exists( ec );
319 catch(
const std::exception & ex )
329 RESTINIO_FMT_FORMAT_STRING(
"after write callback failed: {}" ),
340 const auto & items = m_current_wg->items();
341 std::size_t total_size{ 0 };
343 for( ;m_next_writable_item_index < items.size() &&
344 writable_item_type_t::trivial_write_operation ==
345 items[ m_next_writable_item_index ].write_type() &&
346 max_iov_len() > m_asio_bufs.size();
347 ++m_next_writable_item_index )
349 const auto & item = items[ m_next_writable_item_index ];
350 m_asio_bufs.emplace_back( item.buf() );
351 total_size += item.size();
354 assert( !m_asio_bufs.empty() );
355 return trivial_write_operation_t{ m_asio_bufs, total_size };
363 m_current_wg->items()[ m_next_writable_item_index++ ].sendfile_operation();
365 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
Write operaton using sendfile.
trivial_write_operation_t & operator=(trivial_write_operation_t &&)=default
std::optional< write_group_t > m_current_wg
Real buffers with data.
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.
void start_next_write_group(std::optional< write_group_t > next_wg) noexcept
Start handlong next write group.
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, std::optional< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in std::optional<Value_Type> if parameter exis...
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.
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
void start_sendfile_operation(default_asio_executor executor, Socket &socket, After_Write_CB after_sendfile_cb)
Start a sendfile operation.
sendfile_operation_shared_ptr_t m_sendfile_operation
Sendfile operation storage context.
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.
void reset() noexcept
Reset write operation context.
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 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