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

Class async_write_message_initiation

example/cpp11/operations/composed_6.cpp:51–195  ·  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

49// To enable this, when implementing an asynchronous operation we must package
50// the initiation step as a function object.
51struct async_write_message_initiation
52{
53 // The initiation function object's call operator is passed the concrete
54 // completion handler produced by the completion token. This completion
55 // handler matches the asynchronous operation's completion handler signature,
56 // which in this example is:
57 //
58 // void(boost::system::error_code error)
59 //
60 // The initiation function object also receives any additional arguments
61 // required to start the operation. (Note: We could have instead passed these
62 // arguments as members in the initiaton function object. However, we should
63 // prefer to propagate them as function call arguments as this allows the
64 // completion token to optimise how they are passed. For example, a lazy
65 // future which defers initiation would need to make a decay-copy of the
66 // arguments, but when using a simple callback the arguments can be trivially
67 // forwarded straight through.)
68 template <typename CompletionHandler>
69 void operator()(CompletionHandler&& completion_handler, tcp::socket& socket,
70 std::unique_ptr<std::string> encoded_message, std::size_t repeat_count,
71 std::unique_ptr<boost::asio::steady_timer> delay_timer) const
72 {
73 // In this example, the composed operation's intermediate completion
74 // handler is implemented as a hand-crafted function object.
75 struct intermediate_completion_handler
76 {
77 // The intermediate completion handler holds a reference to the socket as
78 // it is used for multiple async_write operations, as well as for
79 // obtaining the I/O executor (see get_executor below).
80 tcp::socket& socket_;
81
82 // The allocated buffer for the encoded message. The std::unique_ptr
83 // smart pointer is move-only, and as a consequence our intermediate
84 // completion handler is also move-only.
85 std::unique_ptr<std::string> encoded_message_;
86
87 // The repeat count remaining.
88 std::size_t repeat_count_;
89
90 // A steady timer used for introducing a delay.
91 std::unique_ptr<boost::asio::steady_timer> delay_timer_;
92
93 // To manage the cycle between the multiple underlying asynchronous
94 // operations, our intermediate completion handler is implemented as a
95 // state machine.
96 enum { starting, waiting, writing } state_;
97
98 // As our composed operation performs multiple underlying I/O operations,
99 // we should maintain a work object against the I/O executor. This tells
100 // the I/O executor that there is still more work to come in the future.
101 boost::asio::executor_work_guard<tcp::socket::executor_type> io_work_;
102
103 // The user-supplied completion handler, called once only on completion
104 // of the entire composed operation.
105 typename std::decay<CompletionHandler>::type handler_;
106
107 // By having a default value for the second argument, this function call
108 // operator matches the completion signature of both the async_write and

Callers 1

async_write_messagesFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected