diff options
Diffstat (limited to '3rdparty/asio/src/doc/overview/strands.qbk')
-rw-r--r-- | 3rdparty/asio/src/doc/overview/strands.qbk | 85 |
1 files changed, 0 insertions, 85 deletions
diff --git a/3rdparty/asio/src/doc/overview/strands.qbk b/3rdparty/asio/src/doc/overview/strands.qbk deleted file mode 100644 index 0b6ff050dc6..00000000000 --- a/3rdparty/asio/src/doc/overview/strands.qbk +++ /dev/null @@ -1,85 +0,0 @@ -[/ - / Copyright (c) 2003-2016 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) - /] - -[section:strands Strands: Use Threads Without Explicit Locking] - -A strand is defined as a strictly sequential invocation of event handlers (i.e. -no concurrent invocation). Use of strands allows execution of code in a -multithreaded program without the need for explicit locking (e.g. using -mutexes). - -Strands may be either implicit or explicit, as illustrated by the following -alternative approaches: - -* Calling io_context::run() from only one thread means all event handlers - execute in an implicit strand, due to the io_context's guarantee that handlers - are only invoked from inside run(). - -* Where there is a single chain of asynchronous operations associated with a - connection (e.g. in a half duplex protocol implementation like HTTP) there is - no possibility of concurrent execution of the handlers. This is an implicit - strand. - -* An explicit strand is an instance of `strand<>` or `io_context::strand`. All - event handler function objects need to be bound to the strand using - `asio::bind_executor()` or otherwise posted/dispatched through the strand - object. - -In the case of composed asynchronous operations, such as `async_read()` or -`async_read_until()`, if a completion handler goes through a strand, then all -intermediate handlers should also go through the same strand. This is needed to -ensure thread safe access for any objects that are shared between the caller -and the composed operation (in the case of `async_read()` it's the socket, -which the caller can `close()` to cancel the operation). - -This is done by partially specialising the `asio::ssociated_executor<>` trait -for all intermediate handlers. This trait forwards to the corresponding trait -specialisation for the final handler: - - struct my_handler - { - void operator()() { ... } - }; - - namespace asio { - - template <class Executor> - struct associated_executor<my_handler, Executor> - { - // Custom implementation of Executor type requirements. - typedef my_executor type; - - // Return a custom executor implementation. - static type get(const my_handler&, const Executor& = Executor()) - { - return my_executor(); - } - }; - - } // namespace asio - -The `asio::bind_executor()` function is a helper to bind a specific executor -object, such as a strand, to a completion handler. This binding automatically -specialises the `associated_executor` trait as shown above. For example, to -bind a strand to a completion handler we would simply write: - - my_socket.async_read_some(my_buffer, - asio::bind_executor(my_strand, - [](error_code ec, size_t length) - { - // ... - })); - -[heading See Also] - -[link asio.reference.bind_executor bind_executor], -[link asio.reference.strand strand], -[link asio.reference.io_context__strand io_context::strand], -[link asio.tutorial.tuttimer5 tutorial Timer.5], -[link asio.examples.cpp03_examples.http_server_3 HTTP server 3 example]. - -[endsect] |