diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp14/operations/composed_6.cpp')
-rw-r--r-- | 3rdparty/asio/src/examples/cpp14/operations/composed_6.cpp | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/3rdparty/asio/src/examples/cpp14/operations/composed_6.cpp b/3rdparty/asio/src/examples/cpp14/operations/composed_6.cpp index d0304de6a99..82c0cd72237 100644 --- a/3rdparty/asio/src/examples/cpp14/operations/composed_6.cpp +++ b/3rdparty/asio/src/examples/cpp14/operations/composed_6.cpp @@ -2,12 +2,13 @@ // composed_6.cpp // ~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include <asio/deferred.hpp> #include <asio/executor_work_guard.hpp> #include <asio/io_context.hpp> #include <asio/ip/tcp.hpp> @@ -42,12 +43,19 @@ auto async_write_messages(tcp::socket& socket, const T& message, std::size_t repeat_count, CompletionToken&& token) // The return type of the initiating function is deduced from the combination - // of CompletionToken type and the completion handler's signature. When the - // completion token is a simple callback, the return type is always void. - // In this example, when the completion token is asio::yield_context - // (used for stackful coroutines) the return type would be also be void, as + // of: + // + // - the CompletionToken type, + // - the completion handler signature, and + // - the asynchronous operation's initiation function object. + // + // When the completion token is a simple callback, the return type is always + // void. In this example, when the completion token is asio::yield_context + // (used for stackful coroutines) the return type would also be void, as // there is no non-error argument to the completion handler. When the - // completion token is asio::use_future it would be std::future<void>. + // completion token is asio::use_future it would be std::future<void>. When + // the completion token is asio::deferred, the return type differs for each + // asynchronous operation. // // In C++14 we can omit the return type as it is automatically deduced from // the return type of asio::async_initiate. @@ -108,9 +116,7 @@ auto async_write_messages(tcp::socket& socket, // As our composed operation performs multiple underlying I/O operations, // we should maintain a work object against the I/O executor. This tells // the I/O executor that there is still more work to come in the future. - typename std::decay<decltype(asio::prefer( - std::declval<tcp::socket::executor_type>(), - asio::execution::outstanding_work.tracked))>::type io_work_; + asio::executor_work_guard<tcp::socket::executor_type> io_work_; // The user-supplied completion handler, called once only on completion // of the entire composed operation. @@ -147,6 +153,9 @@ auto async_write_messages(tcp::socket& socket, // This point is reached only on completion of the entire composed // operation. + // We no longer have any future work coming for the I/O executor. + io_work_.reset(); + // Deallocate the encoded message before calling the user-supplied // completion handler. encoded_message_.reset(); @@ -197,8 +206,7 @@ auto async_write_messages(tcp::socket& socket, socket, std::move(encoded_message), repeat_count, std::move(delay_timer), intermediate_completion_handler::starting, - asio::prefer(socket.get_executor(), - asio::execution::outstanding_work.tracked), + asio::make_work_guard(socket.get_executor()), std::forward<decltype(completion_handler)>(completion_handler)}); }; @@ -262,6 +270,39 @@ void test_callback() //------------------------------------------------------------------------------ +void test_deferred() +{ + asio::io_context io_context; + + tcp::acceptor acceptor(io_context, {tcp::v4(), 55555}); + tcp::socket socket = acceptor.accept(); + + // Test our asynchronous operation using the deferred completion token. This + // token causes the operation's initiating function to package up the + // operation with its arguments to return a function object, which may then be + // used to launch the asynchronous operation. + auto op = async_write_messages(socket, + "Testing deferred\r\n", 5, asio::deferred); + + // Launch the operation using a lambda as a callback. + std::move(op)( + [](const std::error_code& error) + { + if (!error) + { + std::cout << "Messages sent\n"; + } + else + { + std::cout << "Error: " << error.message() << "\n"; + } + }); + + io_context.run(); +} + +//------------------------------------------------------------------------------ + void test_future() { asio::io_context io_context; @@ -294,5 +335,6 @@ void test_future() int main() { test_callback(); + test_deferred(); test_future(); } |