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

Class async_write_message_initiation

example/cpp11/operations/composed_5.cpp:47–140  ·  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

45// To enable this, when implementing an asynchronous operation we must package
46// the initiation step as a function object.
47struct async_write_message_initiation
48{
49 // The initiation function object's call operator is passed the concrete
50 // completion handler produced by the completion token. This completion
51 // handler matches the asynchronous operation's completion handler signature,
52 // which in this example is:
53 //
54 // void(boost::system::error_code error)
55 //
56 // The initiation function object also receives any additional arguments
57 // required to start the operation. (Note: We could have instead passed these
58 // arguments as members in the initiaton function object. However, we should
59 // prefer to propagate them as function call arguments as this allows the
60 // completion token to optimise how they are passed. For example, a lazy
61 // future which defers initiation would need to make a decay-copy of the
62 // arguments, but when using a simple callback the arguments can be trivially
63 // forwarded straight through.)
64 template <typename CompletionHandler>
65 void operator()(CompletionHandler&& completion_handler,
66 tcp::socket& socket, std::unique_ptr<std::string> encoded_message) const
67 {
68 // In this example, the composed operation's intermediate completion
69 // handler is implemented as a hand-crafted function object, rather than
70 // using a lambda or std::bind.
71 struct intermediate_completion_handler
72 {
73 // The intermediate completion handler holds a reference to the socket so
74 // that it can obtain the I/O executor (see get_executor below).
75 tcp::socket& socket_;
76
77 // The allocated buffer for the encoded message. The std::unique_ptr
78 // smart pointer is move-only, and as a consequence our intermediate
79 // completion handler is also move-only.
80 std::unique_ptr<std::string> encoded_message_;
81
82 // The user-supplied completion handler.
83 typename std::decay<CompletionHandler>::type handler_;
84
85 // The function call operator matches the completion signature of the
86 // async_write operation.
87 void operator()(const boost::system::error_code& error, std::size_t /*n*/)
88 {
89 // Deallocate the encoded message before calling the user-supplied
90 // completion handler.
91 encoded_message_.reset();
92
93 // Call the user-supplied handler with the result of the operation.
94 // The arguments must match the completion signature of our composed
95 // operation.
96 handler_(error);
97 }
98
99 // It is essential to the correctness of our composed operation that we
100 // preserve the executor of the user-supplied completion handler. With a
101 // hand-crafted function object we can do this by defining a nested type
102 // executor_type and member function get_executor. These obtain the
103 // completion handler's associated executor, and default to the I/O
104 // executor - in this case the executor of the socket - if the completion

Callers 1

async_write_messageFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected