Botan  2.15.0
Crypto and TLS for C++11
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator > Class Template Reference

#include <asio_async_ops.h>

Inheritance diagram for Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >:

Public Types

using allocator_type = boost::asio::associated_allocator_t< Handler, Allocator >
 
using executor_type = boost::asio::associated_executor_t< Handler, Executor1 >
 

Public Member Functions

allocator_type get_allocator () const noexcept
 
executor_type get_executor () const noexcept
 

Protected Member Functions

template<class HandlerT >
 AsyncBase (HandlerT &&handler, const Executor1 &executor)
 
template<class... Args>
void complete_now (Args &&... args)
 

Protected Attributes

Handler m_handler
 
boost::asio::executor_work_guard< Executor1 > m_work_guard_1
 

Detailed Description

template<class Handler, class Executor1, class Allocator>
class Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >

Base class for asynchronous stream operations.

Asynchronous operations, used for example to implement an interface for boost::asio::async_read_some and boost::asio::async_write_some, are based on boost::asio::coroutines. Derived operations should implement a call operator and invoke it with the correct parameters upon construction. The call operator needs to make sure that the user-provided handler is not called directly. Typically, yield / reenter is used for this in the following fashion:

void operator()(boost::system::error_code ec, std::size_t bytes_transferred, bool isContinuation = true)
{
reenter(this)
{
// operation specific logic, repeatedly interacting with the stream_core and the next_layer (socket)
// make sure intermediate initiating function is called
if(!isContinuation)
{
yield next_layer.async_operation(empty_buffer, this);
}
// call the completion handler
complete_now(error_code, bytes_transferred);
}
}

Once the operation is completed and ready to call the completion handler it checks if an intermediate initiating function has been called using the isContinuation parameter. If not, it will call an asynchronous operation, such as async_read_some, with and empty buffer, set the object itself as the handler, and yield. As a result, the call operator will be invoked again, this time as a continuation, and will jump to the location where it yielded before using reenter. It is now safe to call the handler function via complete_now.

Template Parameters
HandlerType of the completion handler
Executor1Type of the asio executor (usually derived from the lower layer)
AllocatorType of the allocator to be used

Definition at line 68 of file asio_async_ops.h.

Member Typedef Documentation

◆ allocator_type

template<class Handler, class Executor1, class Allocator>
using Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::allocator_type = boost::asio::associated_allocator_t<Handler, Allocator>

Definition at line 71 of file asio_async_ops.h.

◆ executor_type

template<class Handler, class Executor1, class Allocator>
using Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::executor_type = boost::asio::associated_executor_t<Handler, Executor1>

Definition at line 72 of file asio_async_ops.h.

Constructor & Destructor Documentation

◆ AsyncBase()

template<class Handler, class Executor1, class Allocator>
template<class HandlerT >
Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::AsyncBase ( HandlerT &&  handler,
const Executor1 &  executor 
)
inlineprotected

Definition at line 86 of file asio_async_ops.h.

87  : m_handler(std::forward<HandlerT>(handler))
88  , m_work_guard_1(executor)
89  {
90  }
boost::asio::executor_work_guard< Executor1 > m_work_guard_1

Member Function Documentation

◆ complete_now()

template<class Handler, class Executor1, class Allocator>
template<class... Args>
void Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::complete_now ( Args &&...  args)
inlineprotected

Call the completion handler.

This function should only be called after an intermediate initiating function has been called.

Parameters
argsArguments forwarded to the completion handler function.

Definition at line 100 of file asio_async_ops.h.

101  {
102  m_work_guard_1.reset();
103  m_handler(std::forward<Args>(args)...);
104  }
boost::asio::executor_work_guard< Executor1 > m_work_guard_1

◆ get_allocator()

template<class Handler, class Executor1, class Allocator>
allocator_type Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::get_allocator ( ) const
inlinenoexcept

Definition at line 74 of file asio_async_ops.h.

75  {
76  return boost::asio::get_associated_allocator(m_handler);
77  }

◆ get_executor()

template<class Handler, class Executor1, class Allocator>
executor_type Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::get_executor ( ) const
inlinenoexcept

Definition at line 79 of file asio_async_ops.h.

80  {
81  return boost::asio::get_associated_executor(m_handler, m_work_guard_1.get_executor());
82  }
boost::asio::executor_work_guard< Executor1 > m_work_guard_1

Member Data Documentation

◆ m_handler

template<class Handler, class Executor1, class Allocator>
Handler Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::m_handler
protected

◆ m_work_guard_1

template<class Handler, class Executor1, class Allocator>
boost::asio::executor_work_guard<Executor1> Botan::TLS::detail::AsyncBase< Handler, Executor1, Allocator >::m_work_guard_1
protected

The documentation for this class was generated from the following file: