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

Class async_write_message_initiation

example/cpp11/operations/composed_3.cpp:47–94  ·  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, const char* message) const
67 {
68 // The async_write operation has a completion handler signature of:
69 //
70 // void(boost::system::error_code error, std::size n)
71 //
72 // This differs from our operation's signature in that it is also passed
73 // the number of bytes transferred as an argument of type std::size_t. We
74 // will adapt our completion handler to async_write's completion handler
75 // signature by using std::bind, which drops the additional argument.
76 //
77 // However, it is essential to the correctness of our composed operation
78 // that we preserve the executor of the user-supplied completion handler.
79 // The std::bind function will not do this for us, so we must do this by
80 // first obtaining the completion handler's associated executor (defaulting
81 // to the I/O executor - in this case the executor of the socket - if the
82 // completion handler does not have its own) ...
83 auto executor = boost::asio::get_associated_executor(
84 completion_handler, socket.get_executor());
85
86 // ... and then binding this executor to our adapted completion handler
87 // using the boost::asio::bind_executor function.
88 boost::asio::async_write(socket,
89 boost::asio::buffer(message, std::strlen(message)),
90 boost::asio::bind_executor(executor,
91 std::bind(std::forward<CompletionHandler>(
92 completion_handler), std::placeholders::_1)));
93 }
94};
95
96template <typename CompletionToken>
97auto async_write_message(tcp::socket& socket,

Callers 1

async_write_messageFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected