MCPcopy Create free account
hub / github.com/boostorg/asio / async_write_message_initiation

Class async_write_message_initiation

example/cpp11/operations/composed_4.cpp:48–110  ·  view source on GitHub ↗

In addition to determining the mechanism by which an asynchronous operation delivers its result, a completion token also determines the time when the operation commences. For example, when the completion token is a simple callback the operation commences before the initiating function returns. However, if the completion token's delivery mechanism uses a future, we might instead want to defer initi

Source from the content-addressed store, hash-verified

46// To enable this, when implementing an asynchronous operation we must package
47// the initiation step as a function object.
48struct async_write_message_initiation
49{
50 // The initiation function object's call operator is passed the concrete
51 // completion handler produced by the completion token. This completion
52 // handler matches the asynchronous operation's completion handler signature,
53 // which in this example is:
54 //
55 // void(boost::system::error_code error)
56 //
57 // The initiation function object also receives any additional arguments
58 // required to start the operation. (Note: We could have instead passed these
59 // arguments as members in the initiaton function object. However, we should
60 // prefer to propagate them as function call arguments as this allows the
61 // completion token to optimise how they are passed. For example, a lazy
62 // future which defers initiation would need to make a decay-copy of the
63 // arguments, but when using a simple callback the arguments can be trivially
64 // forwarded straight through.)
65 template <typename CompletionHandler>
66 void operator()(CompletionHandler&& completion_handler,
67 tcp::socket& socket, const char* message) const
68 {
69 // The post operation has a completion handler signature of:
70 //
71 // void()
72 //
73 // and the async_write operation has a completion handler signature of:
74 //
75 // void(boost::system::error_code error, std::size n)
76 //
77 // Both of these operations' completion handler signatures differ from our
78 // operation's completion handler signature. We will adapt our completion
79 // handler to these signatures by using std::bind, which drops the
80 // additional arguments.
81 //
82 // However, it is essential to the correctness of our composed operation
83 // that we preserve the executor of the user-supplied completion handler.
84 // The std::bind function will not do this for us, so we must do this by
85 // first obtaining the completion handler's associated executor (defaulting
86 // to the I/O executor - in this case the executor of the socket - if the
87 // completion handler does not have its own) ...
88 auto executor = boost::asio::get_associated_executor(
89 completion_handler, socket.get_executor());
90
91 // ... and then binding this executor to our adapted completion handler
92 // using the boost::asio::bind_executor function.
93 std::size_t length = std::strlen(message);
94 if (length == 0)
95 {
96 boost::asio::post(
97 boost::asio::bind_executor(executor,
98 std::bind(std::forward<CompletionHandler>(completion_handler),
99 boost::asio::error::invalid_argument)));
100 }
101 else
102 {
103 boost::asio::async_write(socket,
104 boost::asio::buffer(message, length),
105 boost::asio::bind_executor(executor,

Callers 1

async_write_messageFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected