summaryrefslogtreecommitdiff
path: root/doc/html/boost_asio/overview/core
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
commit3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch)
tree5c1733853892b8397d67706fa453a9bd978d2102 /doc/html/boost_asio/overview/core
parent88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff)
downloadboost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.gz
boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.bz2
boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.zip
Imported Upstream version 1.66.0upstream/1.66.0
Diffstat (limited to 'doc/html/boost_asio/overview/core')
-rw-r--r--doc/html/boost_asio/overview/core/allocation.html62
-rw-r--r--doc/html/boost_asio/overview/core/async.html10
-rw-r--r--doc/html/boost_asio/overview/core/basics.html28
-rw-r--r--doc/html/boost_asio/overview/core/buffers.html10
-rw-r--r--doc/html/boost_asio/overview/core/concurrency_hint.html175
-rw-r--r--doc/html/boost_asio/overview/core/coroutine.html61
-rw-r--r--doc/html/boost_asio/overview/core/handler_tracking.html325
-rw-r--r--doc/html/boost_asio/overview/core/reactor.html13
-rw-r--r--doc/html/boost_asio/overview/core/spawn.html111
-rw-r--r--doc/html/boost_asio/overview/core/strands.html96
-rw-r--r--doc/html/boost_asio/overview/core/threads.html18
11 files changed, 724 insertions, 185 deletions
diff --git a/doc/html/boost_asio/overview/core/allocation.html b/doc/html/boost_asio/overview/core/allocation.html
index f7662d09d4..c29f0215c4 100644
--- a/doc/html/boost_asio/overview/core/allocation.html
+++ b/doc/html/boost_asio/overview/core/allocation.html
@@ -44,26 +44,62 @@
<p>
Given a copy of a user-defined <code class="computeroutput"><span class="identifier">Handler</span></code>
object <code class="computeroutput"><span class="identifier">h</span></code>, if the implementation
- needs to allocate memory associated with that handler it will execute the
- code:
+ needs to allocate memory associated with that handler it will obtain an
+ allocator using the <code class="computeroutput"><span class="identifier">get_associated_allocator</span></code>
+ function. For example:
</p>
-<pre class="programlisting"><span class="keyword">void</span><span class="special">*</span> <span class="identifier">pointer</span> <span class="special">=</span> <span class="identifier">asio_handler_allocate</span><span class="special">(</span><span class="identifier">size</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">h</span><span class="special">);</span>
+<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">Handler</span><span class="special">&gt;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span>
</pre>
<p>
- Similarly, to deallocate the memory it will execute:
+ The associated allocator must satisfy the standard Allocator requirements.
</p>
-<pre class="programlisting"><span class="identifier">asio_handler_deallocate</span><span class="special">(</span><span class="identifier">pointer</span><span class="special">,</span> <span class="identifier">size</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">h</span><span class="special">);</span>
-</pre>
<p>
- These functions are located using argument-dependent lookup. The implementation
- provides default implementations of the above functions in the <code class="computeroutput"><span class="identifier">asio</span></code> namespace:
+ By default, handlers use the standard allocator (which is implemented in
+ terms of <code class="computeroutput"><span class="special">::</span><span class="keyword">operator</span>
+ <span class="keyword">new</span><span class="special">()</span></code>
+ and <code class="computeroutput"><span class="special">::</span><span class="keyword">operator</span>
+ <span class="keyword">delete</span><span class="special">()</span></code>).
+ The allocator may be customised for a particular handler type by specifying
+ a nested type <code class="computeroutput"><span class="identifier">allocator_type</span></code>
+ and member function <code class="computeroutput"><span class="identifier">get_allocator</span><span class="special">()</span></code>:
</p>
-<pre class="programlisting"><span class="keyword">void</span><span class="special">*</span> <span class="identifier">asio_handler_allocate</span><span class="special">(</span><span class="identifier">size_t</span><span class="special">,</span> <span class="special">...);</span>
-<span class="keyword">void</span> <span class="identifier">asio_handler_deallocate</span><span class="special">(</span><span class="keyword">void</span><span class="special">*,</span> <span class="identifier">size_t</span><span class="special">,</span> <span class="special">...);</span>
+<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_handler</span>
+<span class="special">{</span>
+<span class="keyword">public</span><span class="special">:</span>
+ <span class="comment">// Custom implementation of Allocator type requirements.</span>
+ <span class="keyword">typedef</span> <span class="identifier">my_allocator</span> <span class="identifier">allocator_type</span><span class="special">;</span>
+
+ <span class="comment">// Return a custom allocator implementation.</span>
+ <span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">my_allocator</span><span class="special">();</span>
+ <span class="special">}</span>
+
+ <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
+<span class="special">};</span>
</pre>
<p>
- which are implemented in terms of <code class="computeroutput"><span class="special">::</span><span class="keyword">operator</span> <span class="keyword">new</span><span class="special">()</span></code> and <code class="computeroutput"><span class="special">::</span><span class="keyword">operator</span> <span class="keyword">delete</span><span class="special">()</span></code> respectively.
+ In more complex cases, the <code class="computeroutput"><span class="identifier">associated_allocator</span></code>
+ template may be partially specialised directly:
</p>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>
+
+ <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
+ <span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">my_handler</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
+ <span class="special">{</span>
+ <span class="comment">// Custom implementation of Allocator type requirements.</span>
+ <span class="keyword">typedef</span> <span class="identifier">my_allocator</span> <span class="identifier">type</span><span class="special">;</span>
+
+ <span class="comment">// Return a custom allocator implementation.</span>
+ <span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">my_handler</span><span class="special">&amp;,</span>
+ <span class="keyword">const</span> <span class="identifier">Allocator</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">())</span> <span class="keyword">noexcept</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">my_allocator</span><span class="special">();</span>
+ <span class="special">}</span>
+ <span class="special">};</span>
+
+<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::asio</span>
+</pre>
<p>
The implementation guarantees that the deallocation will occur before the
associated handler is invoked, which means the memory is ready to be reused
@@ -84,8 +120,8 @@
Also</a>
</h6>
<p>
- <a class="link" href="../../reference/asio_handler_allocate.html" title="asio_handler_allocate">asio_handler_allocate</a>,
- <a class="link" href="../../reference/asio_handler_deallocate.html" title="asio_handler_deallocate">asio_handler_deallocate</a>,
+ <a class="link" href="../../reference/associated_allocator.html" title="associated_allocator">associated_allocator</a>,
+ <a class="link" href="../../reference/get_associated_allocator.html" title="get_associated_allocator">get_associated_allocator</a>,
<a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.allocation">custom memory
allocation example (C++03)</a>, <a class="link" href="../../examples/cpp11_examples.html#boost_asio.examples.cpp11_examples.allocation">custom
memory allocation example (C++11)</a>.
diff --git a/doc/html/boost_asio/overview/core/async.html b/doc/html/boost_asio/overview/core/async.html
index acffd3fcb3..80f3abf156 100644
--- a/doc/html/boost_asio/overview/core/async.html
+++ b/doc/html/boost_asio/overview/core/async.html
@@ -61,8 +61,8 @@
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Executes asynchronous operations and queues events on a completion event
- queue when operations complete. From a high-level point of view, services
- like <code class="computeroutput"><span class="identifier">stream_socket_service</span></code>
+ queue when operations complete. From a high-level point of view, internal
+ services like <code class="computeroutput"><span class="identifier">reactive_socket_service</span></code>
are asynchronous operation processors.
</p></blockquote></div>
<p>
@@ -92,7 +92,7 @@
<div class="blockquote"><blockquote class="blockquote"><p>
Calls the asynchronous event demultiplexer to dequeue events, and dispatches
the completion handler (i.e. invokes the function object) associated
- with the event. This abstraction is represented by the <code class="computeroutput"><span class="identifier">io_service</span></code> class.
+ with the event. This abstraction is represented by the <code class="computeroutput"><span class="identifier">io_context</span></code> class.
</p></blockquote></div>
<p>
&#8212; Initiator
@@ -101,7 +101,7 @@
Application-specific code that starts asynchronous operations. The initiator
interacts with an asynchronous operation processor via a high-level interface
such as <code class="computeroutput"><span class="identifier">basic_stream_socket</span></code>,
- which in turn delegates to a service like <code class="computeroutput"><span class="identifier">stream_socket_service</span></code>.
+ which in turn delegates to a service like <code class="computeroutput"><span class="identifier">reactive_socket_service</span></code>.
</p></blockquote></div>
<h6>
<a name="boost_asio.overview.core.async.h1"></a>
@@ -160,7 +160,7 @@
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This is implemented by the operating system, and is associated with an
- I/O completion port. There is one I/O completion port for each <code class="computeroutput"><span class="identifier">io_service</span></code> instance.
+ I/O completion port. There is one I/O completion port for each <code class="computeroutput"><span class="identifier">io_context</span></code> instance.
</p></blockquote></div>
<p>
&#8212; Asynchronous Event Demultiplexer
diff --git a/doc/html/boost_asio/overview/core/basics.html b/doc/html/boost_asio/overview/core/basics.html
index d5e618a58b..2fd0eec986 100644
--- a/doc/html/boost_asio/overview/core/basics.html
+++ b/doc/html/boost_asio/overview/core/basics.html
@@ -41,18 +41,18 @@
<span class="inlinemediaobject"><img src="../../sync_op.png" alt="sync_op"></span>
</p>
<p>
- <span class="bold"><strong>Your program</strong></span> will have at least one <span class="bold"><strong>io_service</strong></span> object. The <span class="bold"><strong>io_service</strong></span>
+ <span class="bold"><strong>Your program</strong></span> will have at least one <span class="bold"><strong>io_context</strong></span> object. The <span class="bold"><strong>io_context</strong></span>
represents <span class="bold"><strong>your program</strong></span>'s link to the
<span class="bold"><strong>operating system</strong></span>'s I/O services.
</p>
-<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_service</span> <span class="identifier">io_service</span><span class="special">;</span>
+<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span> <span class="identifier">io_context</span><span class="special">;</span>
</pre>
<p>
To perform I/O operations <span class="bold"><strong>your program</strong></span>
will need an <span class="bold"><strong>I/O object</strong></span> such as a TCP
socket:
</p>
-<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">io_service</span><span class="special">);</span>
+<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">io_context</span><span class="special">);</span>
</pre>
<p>
When a synchronous connect operation is performed, the following sequence
@@ -66,17 +66,17 @@
</pre>
<p>
2. The <span class="bold"><strong>I/O object</strong></span> forwards the request
- to the <span class="bold"><strong>io_service</strong></span>.
+ to the <span class="bold"><strong>io_context</strong></span>.
</p>
<p>
- 3. The <span class="bold"><strong>io_service</strong></span> calls on the <span class="bold"><strong>operating system</strong></span> to perform the connect operation.
+ 3. The <span class="bold"><strong>io_context</strong></span> calls on the <span class="bold"><strong>operating system</strong></span> to perform the connect operation.
</p>
<p>
4. The <span class="bold"><strong>operating system</strong></span> returns the result
- of the operation to the <span class="bold"><strong>io_service</strong></span>.
+ of the operation to the <span class="bold"><strong>io_context</strong></span>.
</p>
<p>
- 5. The <span class="bold"><strong>io_service</strong></span> translates any error
+ 5. The <span class="bold"><strong>io_context</strong></span> translates any error
resulting from the operation into an object of type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span></code>.
An <code class="computeroutput"><span class="identifier">error_code</span></code> may be compared
with specific values, or tested as a boolean (where a <code class="computeroutput"><span class="keyword">false</span></code>
@@ -122,10 +122,10 @@
</p>
<p>
2. The <span class="bold"><strong>I/O object</strong></span> forwards the request
- to the <span class="bold"><strong>io_service</strong></span>.
+ to the <span class="bold"><strong>io_context</strong></span>.
</p>
<p>
- 3. The <span class="bold"><strong>io_service</strong></span> signals to the <span class="bold"><strong>operating system</strong></span> that it should start an asynchronous
+ 3. The <span class="bold"><strong>io_context</strong></span> signals to the <span class="bold"><strong>operating system</strong></span> that it should start an asynchronous
connect.
</p>
<p>
@@ -138,17 +138,17 @@
<p>
4. The <span class="bold"><strong>operating system</strong></span> indicates that
the connect operation has completed by placing the result on a queue, ready
- to be picked up by the <span class="bold"><strong>io_service</strong></span>.
+ to be picked up by the <span class="bold"><strong>io_context</strong></span>.
</p>
<p>
- 5. <span class="bold"><strong>Your program</strong></span> must make a call to <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>
- (or to one of the similar <span class="bold"><strong>io_service</strong></span> member
- functions) in order for the result to be retrieved. A call to <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>
+ 5. <span class="bold"><strong>Your program</strong></span> must make a call to <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>
+ (or to one of the similar <span class="bold"><strong>io_context</strong></span> member
+ functions) in order for the result to be retrieved. A call to <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>
blocks while there are unfinished asynchronous operations, so you would
typically call it as soon as you have started your first asynchronous operation.
</p>
<p>
- 6. While inside the call to <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, the <span class="bold"><strong>io_service</strong></span>
+ 6. While inside the call to <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, the <span class="bold"><strong>io_context</strong></span>
dequeues the result of the operation, translates it into an <code class="computeroutput"><span class="identifier">error_code</span></code>, and then passes it to <span class="bold"><strong>your completion handler</strong></span>.
</p>
<p>
diff --git a/doc/html/boost_asio/overview/core/buffers.html b/doc/html/boost_asio/overview/core/buffers.html
index 18f51748e6..5950760055 100644
--- a/doc/html/boost_asio/overview/core/buffers.html
+++ b/doc/html/boost_asio/overview/core/buffers.html
@@ -83,10 +83,10 @@
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
</li>
<li class="listitem">
- Type safety violations must be explicitly requested using the <code class="computeroutput"><span class="identifier">buffer_cast</span></code> function. In general
- an application should never need to do this, but it is required by
- the library implementation to pass the raw memory to the underlying
- operating system functions.
+ The underlying memory is explicitly accessed using the <code class="computeroutput"><span class="identifier">data</span><span class="special">()</span></code>
+ member function. In general an application should never need to do
+ this, but it is required by the library implementation to pass the
+ raw memory to the underlying operating system functions.
</li>
</ul></div>
<p>
@@ -117,7 +117,7 @@
member function. The return type of this function meets the <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code> requirements.
</li>
<li class="listitem">
- The output sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/data.html" title="basic_streambuf::data">prepare()</a>
+ The output sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/prepare.html" title="basic_streambuf::prepare">prepare()</a>
member function. The return type of this function meets the <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code> requirements.
</li>
<li class="listitem">
diff --git a/doc/html/boost_asio/overview/core/concurrency_hint.html b/doc/html/boost_asio/overview/core/concurrency_hint.html
new file mode 100644
index 0000000000..ac2b87339c
--- /dev/null
+++ b/doc/html/boost_asio/overview/core/concurrency_hint.html
@@ -0,0 +1,175 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Concurrency Hints</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
+<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
+<link rel="up" href="../core.html" title="Core Concepts and Functionality">
+<link rel="prev" href="handler_tracking.html" title="Handler Tracking">
+<link rel="next" href="coroutine.html" title="Stackless Coroutines">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="handler_tracking.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="coroutine.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="boost_asio.overview.core.concurrency_hint"></a><a class="link" href="concurrency_hint.html" title="Concurrency Hints">Concurrency
+ Hints</a>
+</h4></div></div></div>
+<p>
+ The <a class="link" href="../../reference/io_context/io_context.html" title="io_context::io_context"><code class="computeroutput"><span class="identifier">io_context</span></code> constructor</a> allows
+ programs to specify a concurrency hint. This is a suggestion to the <code class="computeroutput"><span class="identifier">io_context</span></code> implementation as to the number
+ of active threads that should be used for running completion handlers.
+ </p>
+<p>
+ When the Windows I/O completion port backend is in use, this value is passed
+ to <code class="literal">CreateIoCompletionPort</code>.
+ </p>
+<p>
+ When a reactor-based backend is used, the implementation recognises the
+ following special concurrency hint values:
+ </p>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Value
+ </p>
+ </th>
+<th>
+ <p>
+ Description
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="number">1</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ The implementation assumes that the <code class="computeroutput"><span class="identifier">io_context</span></code>
+ will be run from a single thread, and applies several optimisations
+ based on this assumption.
+ </p>
+ <p>
+ For example, when a handler is posted from within another handler,
+ the new handler is added to a fast thread-local queue (with the
+ consequence that the new handler is held back until the currently
+ executing handler finishes).
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_CONCURRENCY_HINT_UNSAFE</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ This special concurrency hint disables locking in both the scheduler
+ and reactor I/O. This hint has the following restrictions:
+ </p>
+ <p>
+ &#8212; Care must be taken to ensure that all operations on the <code class="computeroutput"><span class="identifier">io_context</span></code> and any of its associated
+ I/O objects (such as sockets and timers) occur in only one thread
+ at a time.
+ </p>
+ <p>
+ &#8212; Asynchronous resolve operations fail with <code class="computeroutput"><span class="identifier">operation_not_supported</span></code>.
+ </p>
+ <p>
+ &#8212; If a <code class="computeroutput"><span class="identifier">signal_set</span></code>
+ is used with the <code class="computeroutput"><span class="identifier">io_context</span></code>,
+ <code class="computeroutput"><span class="identifier">signal_set</span></code> objects
+ cannot be used with any other io_context in the program.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ This special concurrency hint disables locking in the reactor
+ I/O. This hint has the following restrictions:
+ </p>
+ <p>
+ &#8212; Care must be taken to ensure that run functions on the <code class="computeroutput"><span class="identifier">io_context</span></code>, and all operations
+ on the context's associated I/O objects (such as sockets and
+ timers), occur in only one thread at a time.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_CONCURRENCY_HINT_SAFE</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ The default. The <code class="computeroutput"><span class="identifier">io_context</span></code>
+ provides full thread safety, and distinct I/O objects may be
+ used from any thread.
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<p>
+ The concurrency hint used by default-constructed <code class="computeroutput">io_context</code>
+ objects can be overridden at compile time by defining the <code class="computeroutput">BOOST_ASIO_CONCURRENCY_HINT_DEFAULT</code>
+ macro. For example, specifying
+ </p>
+<pre class="programlisting">-DBOOST_ASIO_CONCURRENCY_HINT_DEFAULT=1
+</pre>
+<p>
+ on the compiler command line means that a concurrency hint of <code class="computeroutput">1</code>
+ is used for all default-constructed <code class="computeroutput">io_context</code> objects in
+ the program. Similarly, the concurrency hint used by <code class="computeroutput">io_context</code>
+ objects constructed with <code class="computeroutput">1</code> can be overridden by defining
+ <code class="computeroutput">BOOST_ASIO_CONCURRENCY_HINT_1</code>. For example, passing
+ </p>
+<pre class="programlisting">-DBOOST_ASIO_CONCURRENCY_HINT_1=BOOST_ASIO_CONCURRENCY_HINT_UNSAFE
+</pre>
+<p>
+ to the compiler will disable thread safety for all of these objects.
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2003-2017 Christopher M. Kohlhoff<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="handler_tracking.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="coroutine.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/doc/html/boost_asio/overview/core/coroutine.html b/doc/html/boost_asio/overview/core/coroutine.html
index 9c80176721..86da571741 100644
--- a/doc/html/boost_asio/overview/core/coroutine.html
+++ b/doc/html/boost_asio/overview/core/coroutine.html
@@ -6,7 +6,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
-<link rel="prev" href="handler_tracking.html" title="Handler Tracking">
+<link rel="prev" href="concurrency_hint.html" title="Concurrency Hints">
<link rel="next" href="spawn.html" title="Stackful Coroutines">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -20,49 +20,48 @@
</tr></table>
<hr>
<div class="spirit-nav">
-<a accesskey="p" href="handler_tracking.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="spawn.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+<a accesskey="p" href="concurrency_hint.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="spawn.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.overview.core.coroutine"></a><a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless Coroutines</a>
</h4></div></div></div>
<p>
- The <a class="link" href="../../reference/coroutine.html" title="coroutine"><code class="computeroutput"><span class="identifier">coroutine</span></code></a>
+ The <a class="link" href="../../reference/coroutine.html" title="coroutine"><code class="computeroutput">coroutine</code></a>
class provides support for stackless coroutines. Stackless coroutines enable
programs to implement asynchronous logic in a synchronous manner, with
minimal overhead, as shown in the following example:
</p>
-<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">session</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">coroutine</span>
-<span class="special">{</span>
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">socket_</span><span class="special">;</span>
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">buffer_</span><span class="special">;</span>
+<pre class="programlisting">struct session : boost::asio::coroutine
+{
+ boost::shared_ptr&lt;tcp::socket&gt; socket_;
+ boost::shared_ptr&lt;std::vector&lt;char&gt; &gt; buffer_;
- <span class="identifier">session</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span> <span class="identifier">socket</span><span class="special">)</span>
- <span class="special">:</span> <span class="identifier">socket_</span><span class="special">(</span><span class="identifier">socket</span><span class="special">),</span>
- <span class="identifier">buffer_</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="number">1024</span><span class="special">))</span>
- <span class="special">{</span>
- <span class="special">}</span>
+ session(boost::shared_ptr&lt;tcp::socket&gt; socket)
+ : socket_(socket),
+ buffer_(new std::vector&lt;char&gt;(1024))
+ {
+ }
- <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span>
- <span class="special">{</span>
- <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span> <span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
- <span class="special">{</span>
- <span class="keyword">for</span> <span class="special">(;;)</span>
- <span class="special">{</span>
- <span class="identifier">yield</span> <span class="identifier">socket_</span><span class="special">-&gt;</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer_</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
- <span class="identifier">yield</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(*</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer_</span><span class="special">,</span> <span class="identifier">n</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
- <span class="special">}</span>
- <span class="special">}</span>
- <span class="special">}</span>
-<span class="special">};</span>
+ void operator()(boost::system::error_code ec = boost::system::error_code(), std::size_t n = 0)
+ {
+ if (!ec) reenter (this)
+ {
+ for (;;)
+ {
+ yield socket_-&gt;async_read_some(boost::asio::buffer(*buffer_), *this);
+ yield boost::asio::async_write(*socket_, boost::asio::buffer(*buffer_, n), *this);
+ }
+ }
+ }
+};
</pre>
<p>
- The <code class="computeroutput"><span class="identifier">coroutine</span></code> class is
- used in conjunction with the pseudo-keywords <code class="computeroutput"><span class="identifier">reenter</span></code>,
- <code class="computeroutput"><span class="identifier">yield</span></code> and <code class="computeroutput"><span class="identifier">fork</span></code>. These are preprocessor macros,
- and are implemented in terms of a <code class="computeroutput"><span class="keyword">switch</span></code>
- statement using a technique similar to Duff's Device. The <a class="link" href="../../reference/coroutine.html" title="coroutine"><code class="computeroutput"><span class="identifier">coroutine</span></code></a> class's documentation
- provides a complete description of these pseudo-keywords.
+ The <code class="computeroutput">coroutine</code> class is used in conjunction with the pseudo-keywords
+ <code class="computeroutput">reenter</code>, <code class="computeroutput">yield</code> and <code class="computeroutput">fork</code>. These are
+ preprocessor macros, and are implemented in terms of a <code class="computeroutput">switch</code>
+ statement using a technique similar to Duff's Device. The <a class="link" href="../../reference/coroutine.html" title="coroutine"><code class="computeroutput">coroutine</code></a>
+ class's documentation provides a complete description of these pseudo-keywords.
</p>
<h6>
<a name="boost_asio.overview.core.coroutine.h0"></a>
@@ -85,7 +84,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
-<a accesskey="p" href="handler_tracking.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="spawn.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+<a accesskey="p" href="concurrency_hint.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="spawn.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
diff --git a/doc/html/boost_asio/overview/core/handler_tracking.html b/doc/html/boost_asio/overview/core/handler_tracking.html
index be065d2498..68279e2f9c 100644
--- a/doc/html/boost_asio/overview/core/handler_tracking.html
+++ b/doc/html/boost_asio/overview/core/handler_tracking.html
@@ -7,7 +7,7 @@
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../core.html" title="Core Concepts and Functionality">
<link rel="prev" href="allocation.html" title="Custom Memory Allocation">
-<link rel="next" href="coroutine.html" title="Stackless Coroutines">
+<link rel="next" href="concurrency_hint.html" title="Concurrency Hints">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
@@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
-<a accesskey="p" href="allocation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="coroutine.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+<a accesskey="p" href="allocation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="concurrency_hint.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
@@ -39,25 +39,30 @@
are. As an illustration, here is the output when you run the HTTP Server
example, handle a single request, then shut down via Ctrl+C:
</p>
-<pre class="programlisting">@asio|1298160085.070638|0*1|signal_set@0x7fff50528f40.async_wait
-@asio|1298160085.070888|0*2|socket@0x7fff50528f60.async_accept
-@asio|1298160085.070913|0|resolver@0x7fff50528e28.cancel
-@asio|1298160118.075438|&gt;2|ec=asio.system:0
-@asio|1298160118.075472|2*3|socket@0xb39048.async_receive
-@asio|1298160118.075507|2*4|socket@0x7fff50528f60.async_accept
-@asio|1298160118.075527|&lt;2|
-@asio|1298160118.075540|&gt;3|ec=asio.system:0,bytes_transferred=122
-@asio|1298160118.075731|3*5|socket@0xb39048.async_send
-@asio|1298160118.075778|&lt;3|
-@asio|1298160118.075793|&gt;5|ec=asio.system:0,bytes_transferred=156
-@asio|1298160118.075831|5|socket@0xb39048.close
-@asio|1298160118.075855|&lt;5|
-@asio|1298160122.827317|&gt;1|ec=asio.system:0,signal_number=2
-@asio|1298160122.827333|1|socket@0x7fff50528f60.close
-@asio|1298160122.827359|&lt;1|
-@asio|1298160122.827370|&gt;4|ec=asio.system:125
-@asio|1298160122.827378|&lt;4|
-@asio|1298160122.827394|0|signal_set@0x7fff50528f40.cancel
+<pre class="programlisting">@asio|1512254357.979980|0*1|signal_set@0x7ffeaaaa20d8.async_wait
+@asio|1512254357.980127|0*2|socket@0x7ffeaaaa20f8.async_accept
+@asio|1512254357.980150|.2|non_blocking_accept,ec=asio.system:11
+@asio|1512254357.980162|0|resolver@0x7ffeaaaa1fd8.cancel
+@asio|1512254368.457147|.2|non_blocking_accept,ec=system:0
+@asio|1512254368.457193|&gt;2|ec=system:0
+@asio|1512254368.457219|2*3|socket@0x55cf39f0a238.async_receive
+@asio|1512254368.457244|.3|non_blocking_recv,ec=system:0,bytes_transferred=141
+@asio|1512254368.457275|2*4|socket@0x7ffeaaaa20f8.async_accept
+@asio|1512254368.457293|.4|non_blocking_accept,ec=asio.system:11
+@asio|1512254368.457301|&lt;2|
+@asio|1512254368.457310|&gt;3|ec=system:0,bytes_transferred=141
+@asio|1512254368.457441|3*5|socket@0x55cf39f0a238.async_send
+@asio|1512254368.457502|.5|non_blocking_send,ec=system:0,bytes_transferred=156
+@asio|1512254368.457511|&lt;3|
+@asio|1512254368.457519|&gt;5|ec=system:0,bytes_transferred=156
+@asio|1512254368.457544|5|socket@0x55cf39f0a238.close
+@asio|1512254368.457559|&lt;5|
+@asio|1512254371.385106|&gt;1|ec=system:0,signal_number=2
+@asio|1512254371.385130|1|socket@0x7ffeaaaa20f8.close
+@asio|1512254371.385163|&lt;1|
+@asio|1512254371.385175|&gt;4|ec=asio.system:125
+@asio|1512254371.385182|&lt;4|
+@asio|1512254371.385202|0|signal_set@0x7ffeaaaa20d8.cancel
</pre>
<p>
Each line is of the form:
@@ -96,7 +101,7 @@
<dd><p>
The handler number <code class="computeroutput">n</code> was destroyed without having been
invoked. This is usually the case for any unfinished asynchronous
- operations when the <code class="computeroutput">io_service</code> is destroyed.
+ operations when the <code class="computeroutput">io_context</code> is destroyed.
</p></dd>
<dt><span class="term">n*m</span></dt>
<dd><p>
@@ -106,10 +111,19 @@
</p></dd>
<dt><span class="term">n</span></dt>
<dd><p>
- The handler number n performed some other operation. The <code class="computeroutput">&lt;description&gt;</code>
- shows what function was called. Currently only <code class="computeroutput">close()</code>
- and <code class="computeroutput">cancel()</code> operations are logged, as these may affect
- the state of pending asynchronous operations.
+ The handler number <code class="computeroutput">n</code> performed some other operation.
+ The <code class="computeroutput">&lt;description&gt;</code> shows what function was called.
+ Currently only <code class="computeroutput">close()</code> and <code class="computeroutput">cancel()</code> operations
+ are logged, as these may affect the state of pending asynchronous
+ operations.
+ </p></dd>
+<dt><span class="term">.n</span></dt>
+<dd><p>
+ The implementation performed a system call as part of the asynchronous
+ operation for which handler number <code class="computeroutput">n</code> is the completion
+ handler. The <code class="computeroutput">&lt;description&gt;</code> shows what function
+ was called and its results. These tracking events are only emitted
+ when using a reactor-based implementation.
</p></dd>
</dl>
</div>
@@ -134,6 +148,263 @@
tool to create a visual representation of the handlers (requires the GraphViz
tool <code class="literal">dot</code>).
</p>
+<h6>
+<a name="boost_asio.overview.core.handler_tracking.h1"></a>
+ <span class="phrase"><a name="boost_asio.overview.core.handler_tracking.custom_tracking"></a></span><a class="link" href="handler_tracking.html#boost_asio.overview.core.handler_tracking.custom_tracking">Custom
+ Tracking</a>
+ </h6>
+<p>
+ Handling tracking may be customised by defining the <code class="computeroutput"><span class="identifier">BOOST_ASIO_CUSTOM_HANDLER_TRACKING</span></code>
+ macro to the name of a header file (enclosed in <code class="computeroutput"><span class="string">""</span></code>
+ or <code class="computeroutput"><span class="special">&lt;&gt;</span></code>). This header
+ file must implement the following preprocessor macros:
+ </p>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Macro
+ </p>
+ </th>
+<th>
+ <p>
+ Description
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_INHERIT_TRACKED_HANDLER</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ Specifies a base class for classes that implement asynchronous
+ operations. When used, the macro immediately follows the class
+ name, so it must have the form <code class="computeroutput"><span class="special">:</span>
+ <span class="keyword">public</span> <span class="identifier">my_class</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ Specifies a base class for classes that implement asynchronous
+ operations. When used, the macro follows other base classes,
+ so it must have the form <code class="computeroutput"><span class="special">,</span>
+ <span class="keyword">public</span> <span class="identifier">my_class</span></code>.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_TRACKING_INIT</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is used to initialise the tracking mechanism.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_CREATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called on creation of an asynchronous operation.
+ <code class="computeroutput"><span class="identifier">args</span></code> is a parenthesised
+ function argument list containing the owning execution context,
+ the tracked handler, the name of the object type, a pointer to
+ the object, the object's native handle, and the operation name.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_COMPLETION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called on completion of an asynchronous
+ operation. <code class="computeroutput"><span class="identifier">args</span></code>
+ is a parenthesised function argument list containing the tracked
+ handler.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_INVOCATION_BEGIN</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called immediately before a completion
+ handler is invoked. <code class="computeroutput"><span class="identifier">args</span></code>
+ is a parenthesised function argument list containing the arguments
+ to the completion handler.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_INVOCATION_END</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called immediately after a completion handler
+ is invoked.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_OPERATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called when some synchronous object operation
+ is called (such as <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">cancel</span><span class="special">()</span></code>). <code class="computeroutput"><span class="identifier">args</span></code>
+ is a parenthesised function argument list containing the owning
+ execution context, the name of the object type, a pointer to
+ the object, the object's native handle, and the operation name.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_REGISTRATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called when an object is registered with
+ the reactor. <code class="computeroutput"><span class="identifier">args</span></code>
+ is a parenthesised function argument list containing the owning
+ execution context, the object's native handle, and a unique registration
+ key.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called when an object is deregistered from
+ the reactor. <code class="computeroutput"><span class="identifier">args</span></code>
+ is a parenthesised function argument list containing the owning
+ execution context, the object's native handle, and a unique registration
+ key.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_READ_EVENT</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ A bitmask constant used to identify reactor read readiness events.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ A bitmask constant used to identify reactor write readiness events.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ A bitmask constant used to identify reactor error readiness events.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_EVENTS</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called when an object registered with the
+ reactor becomes ready. <code class="computeroutput"><span class="identifier">args</span></code>
+ is a parenthesised function argument list containing the owning
+ execution context, the unique registration key, and a bitmask
+ of the ready events.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_REACTOR_OPERATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ An expression that is called when the implementation performs
+ a system call as part of a reactor-based asynchronous operation.
+ <code class="computeroutput"><span class="identifier">args</span></code> is a parenthesised
+ function argument list containing the tracked handler, the operation
+ name, the error code produced by the operation, and (optionally)
+ the number of bytes transferred.
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<h6>
+<a name="boost_asio.overview.core.handler_tracking.h2"></a>
+ <span class="phrase"><a name="boost_asio.overview.core.handler_tracking.see_also"></a></span><a class="link" href="handler_tracking.html#boost_asio.overview.core.handler_tracking.see_also">See Also</a>
+ </h6>
+<p>
+ <a class="link" href="../../examples/cpp11_examples.html#boost_asio.examples.cpp11_examples.handler_tracking">Custom
+ handler tracking example</a>.
+ </p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
@@ -145,7 +416,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
-<a accesskey="p" href="allocation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="coroutine.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+<a accesskey="p" href="allocation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="concurrency_hint.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
diff --git a/doc/html/boost_asio/overview/core/reactor.html b/doc/html/boost_asio/overview/core/reactor.html
index eec7413607..4afd7ec4a3 100644
--- a/doc/html/boost_asio/overview/core/reactor.html
+++ b/doc/html/boost_asio/overview/core/reactor.html
@@ -29,19 +29,19 @@
<p>
Sometimes a program must be integrated with a third-party library that
wants to perform the I/O operations itself. To facilitate this, Boost.Asio
- includes a <code class="computeroutput"><span class="identifier">null_buffers</span></code>
- type that can be used with both read and write operations. A <code class="computeroutput"><span class="identifier">null_buffers</span></code> operation doesn't return
- until the I/O object is "ready" to perform the operation.
+ includes synchronous and asynchronous operations that may be used to wait
+ for a socket to become ready to read, ready to write, or to have a pending
+ error condition.
</p>
<p>
As an example, to perform a non-blocking read something like the following
may be used:
</p>
-<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_service</span><span class="special">);</span>
+<pre class="programlisting"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket</span><span class="special">(</span><span class="identifier">my_io_context</span><span class="special">);</span>
<span class="special">...</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">non_blocking</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>
<span class="special">...</span>
-<span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">null_buffers</span><span class="special">(),</span> <span class="identifier">read_handler</span><span class="special">);</span>
+<span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">::</span><span class="identifier">wait_read</span><span class="special">,</span> <span class="identifier">read_handler</span><span class="special">);</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">read_handler</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
@@ -62,7 +62,8 @@
Also</a>
</h6>
<p>
- <a class="link" href="../../reference/null_buffers.html" title="null_buffers">null_buffers</a>,
+ <a class="link" href="../../reference/basic_socket/wait.html" title="basic_socket::wait">basic_socket::wait()</a>,
+ <a class="link" href="../../reference/basic_socket/async_wait.html" title="basic_socket::async_wait">basic_socket::async_wait()</a>,
<a class="link" href="../../reference/basic_socket/non_blocking.html" title="basic_socket::non_blocking">basic_socket::non_blocking()</a>,
<a class="link" href="../../reference/basic_socket/native_non_blocking.html" title="basic_socket::native_non_blocking">basic_socket::native_non_blocking()</a>,
<a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.nonblocking">nonblocking
diff --git a/doc/html/boost_asio/overview/core/spawn.html b/doc/html/boost_asio/overview/core/spawn.html
index 3ae397c377..c57e00bdb0 100644
--- a/doc/html/boost_asio/overview/core/spawn.html
+++ b/doc/html/boost_asio/overview/core/spawn.html
@@ -27,57 +27,59 @@
<a name="boost_asio.overview.core.spawn"></a><a class="link" href="spawn.html" title="Stackful Coroutines">Stackful Coroutines</a>
</h4></div></div></div>
<p>
- The <a class="link" href="../../reference/spawn.html" title="spawn"><code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code></a> function is a high-level wrapper
- for running stackful coroutines. It is based on the Boost.Coroutine library.
- The <code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code>
- function enables programs to implement asynchronous logic in a synchronous
- manner, as shown in the following example:
+ The <a class="link" href="../../reference/spawn.html" title="spawn"><code class="computeroutput">spawn()</code></a>
+ function is a high-level wrapper for running stackful coroutines. It is
+ based on the Boost.Coroutine library. The <code class="computeroutput">spawn()</code> function
+ enables programs to implement asynchronous logic in a synchronous manner,
+ as shown in the following example:
</p>
-<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">spawn</span><span class="special">(</span><span class="identifier">my_strand</span><span class="special">,</span> <span class="identifier">do_echo</span><span class="special">);</span>
+<pre class="programlisting">boost::asio::spawn(my_strand, do_echo);
-<span class="comment">// ...</span>
+// ...
-<span class="keyword">void</span> <span class="identifier">do_echo</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">)</span>
-<span class="special">{</span>
- <span class="keyword">try</span>
- <span class="special">{</span>
- <span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">128</span><span class="special">];</span>
- <span class="keyword">for</span> <span class="special">(;;)</span>
- <span class="special">{</span>
- <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span>
- <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
+void do_echo(boost::asio::yield_context yield)
+{
+ try
+ {
+ char data[128];
+ for (;;)
+ {
+ std::size_t length =
+ my_socket.async_read_some(
+ boost::asio::buffer(data), yield);
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">my_socket</span><span class="special">,</span>
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">length</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
- <span class="special">}</span>
- <span class="special">}</span>
- <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
- <span class="special">{</span>
- <span class="comment">// ...</span>
- <span class="special">}</span>
-<span class="special">}</span>
+ boost::asio::async_write(my_socket,
+ boost::asio::buffer(data, length), yield);
+ }
+ }
+ catch (std::exception&amp; e)
+ {
+ // ...
+ }
+}
</pre>
<p>
- The first argument to <code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code> may be a <a class="link" href="../../reference/io_service__strand.html" title="io_service::strand"><code class="computeroutput"><span class="identifier">strand</span></code></a>, <a class="link" href="../../reference/io_service.html" title="io_service"><code class="computeroutput"><span class="identifier">io_service</span></code></a>, or <a class="link" href="../../reference/CompletionHandler.html" title="Completion handler requirements">completion
- handler</a>. This argument determines the context in which the coroutine
- is permitted to execute. For example, a server's per-client object may
- consist of multiple coroutines; they should all run on the same <code class="computeroutput"><span class="identifier">strand</span></code> so that no explicit synchronisation
- is required.
+ The first argument to <code class="computeroutput">spawn()</code> may be a <a class="link" href="../../reference/io_context__strand.html" title="io_context::strand"><code class="computeroutput">strand</code></a>,
+ <a class="link" href="../../reference/io_context.html" title="io_context"><code class="computeroutput">io_context</code></a>,
+ or <a class="link" href="../../reference/CompletionHandler.html" title="Completion handler requirements">completion handler</a>.
+ This argument determines the context in which the coroutine is permitted
+ to execute. For example, a server's per-client object may consist of multiple
+ coroutines; they should all run on the same <code class="computeroutput">strand</code> so that
+ no explicit synchronisation is required.
</p>
<p>
The second argument is a function object with signature:
</p>
-<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">coroutine</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">);</span>
+<pre class="programlisting">void coroutine(boost::asio::yield_context yield);
</pre>
<p>
that specifies the code to be run as part of the coroutine. The parameter
- <code class="computeroutput"><span class="identifier">yield</span></code> may be passed to
- an asynchronous operation in place of the completion handler, as in:
+ <code class="computeroutput">yield</code> may be passed to an asynchronous operation in place
+ of the completion handler, as in:
</p>
-<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span>
- <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
+<pre class="programlisting">std::size_t length =
+ my_socket.async_read_some(
+ boost::asio::buffer(data), yield);
</pre>
<p>
This starts the asynchronous operation and suspends the coroutine. The
@@ -87,42 +89,39 @@
<p>
Where an asynchronous operation's handler signature has the form:
</p>
-<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">result_type</span> <span class="identifier">result</span><span class="special">);</span>
+<pre class="programlisting">void handler(boost::system::error_code ec, result_type result);
</pre>
<p>
- the initiating function returns the result_type. In the <code class="computeroutput"><span class="identifier">async_read_some</span></code>
- example above, this is <code class="computeroutput"><span class="identifier">size_t</span></code>.
- If the asynchronous operation fails, the <code class="computeroutput"><span class="identifier">error_code</span></code>
- is converted into a <code class="computeroutput"><span class="identifier">system_error</span></code>
+ the initiating function returns the result_type. In the <code class="computeroutput">async_read_some</code>
+ example above, this is <code class="computeroutput">size_t</code>. If the asynchronous operation
+ fails, the <code class="computeroutput">error_code</code> is converted into a <code class="computeroutput">system_error</code>
exception and thrown.
</p>
<p>
Where a handler signature has the form:
</p>
-<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">);</span>
+<pre class="programlisting">void handler(boost::system::error_code ec);
</pre>
<p>
- the initiating function returns <code class="computeroutput"><span class="keyword">void</span></code>.
- As above, an error is passed back to the coroutine as a <code class="computeroutput"><span class="identifier">system_error</span></code>
- exception.
+ the initiating function returns <code class="computeroutput">void</code>. As above, an error is
+ passed back to the coroutine as a <code class="computeroutput">system_error</code> exception.
</p>
<p>
- To collect the <code class="computeroutput"><span class="identifier">error_code</span></code>
- from an operation, rather than have it throw an exception, associate the
- output variable with the <code class="computeroutput"><span class="identifier">yield_context</span></code>
+ To collect the <code class="computeroutput">error_code</code> from an operation, rather than have
+ it throw an exception, associate the output variable with the <code class="computeroutput">yield_context</code>
as follows:
</p>
-<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
-<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span>
- <span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span>
- <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">[</span><span class="identifier">ec</span><span class="special">]);</span>
+<pre class="programlisting">boost::system::error_code ec;
+std::size_t length =
+ my_socket.async_read_some(
+ boost::asio::buffer(data), yield[ec]);
</pre>
<p>
- <span class="bold"><strong>Note:</strong></span> if <code class="computeroutput"><span class="identifier">spawn</span><span class="special">()</span></code> is used with a custom completion handler
- of type <code class="computeroutput"><span class="identifier">Handler</span></code>, the function
+ <span class="bold"><strong>Note:</strong></span> if <code class="computeroutput">spawn()</code> is used
+ with a custom completion handler of type <code class="computeroutput">Handler</code>, the function
object signature is actually:
</p>
-<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">coroutine</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">basic_yield_context</span><span class="special">&lt;</span><span class="identifier">Handler</span><span class="special">&gt;</span> <span class="identifier">yield</span><span class="special">);</span>
+<pre class="programlisting">void coroutine(boost::asio::basic_yield_context&lt;Handler&gt; yield);
</pre>
<h6>
<a name="boost_asio.overview.core.spawn.h0"></a>
diff --git a/doc/html/boost_asio/overview/core/strands.html b/doc/html/boost_asio/overview/core/strands.html
index 522c4ded43..3326545ebd 100644
--- a/doc/html/boost_asio/overview/core/strands.html
+++ b/doc/html/boost_asio/overview/core/strands.html
@@ -39,8 +39,8 @@
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
- Calling io_service::run() from only one thread means all event handlers
- execute in an implicit strand, due to the io_service's guarantee that
+ 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().
</li>
<li class="listitem">
@@ -50,10 +50,10 @@
This is an implicit strand.
</li>
<li class="listitem">
- An explicit strand is an instance of <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">strand</span></code>.
- All event handler function objects need to be wrapped using <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">strand</span><span class="special">::</span><span class="identifier">wrap</span><span class="special">()</span></code>
- or otherwise posted/dispatched through the <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">strand</span></code>
- object.
+ An explicit strand is an instance of <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;&gt;</span></code> or <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">strand</span></code>.
+ All event handler function objects need to be bound to the strand using
+ <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">()</span></code>
+ or otherwise posted/dispatched through the strand object.
</li>
</ul></div>
<p>
@@ -63,34 +63,92 @@
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 <code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code> it's the socket, which the caller can
- close() to cancel the operation). This is done by having hook functions
- for all intermediate handlers which forward the calls to the customisable
- hook associated with the final handler:
+ <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>
+ to cancel the operation).
+ </p>
+<p>
+ To achieve this, all asynchronous operations obtain the handler's associated
+ executor by using the <code class="computeroutput"><span class="identifier">get_associated_executor</span></code>
+ function. For example:
+ </p>
+<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">Handler</span><span class="special">&gt;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span>
+</pre>
+<p>
+ The associated executor must satisfy the Executor requirements. It will
+ be used by the asynchronous operation to submit both intermediate and final
+ handlers for execution.
+ </p>
+<p>
+ The executor may be customised for a particular handler type by specifying
+ a nested type <code class="computeroutput"><span class="identifier">executor_type</span></code>
+ and member function <code class="computeroutput"><span class="identifier">get_executor</span><span class="special">()</span></code>:
+ </p>
+<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_handler</span>
+<span class="special">{</span>
+<span class="keyword">public</span><span class="special">:</span>
+ <span class="comment">// Custom implementation of Executor type requirements.</span>
+ <span class="keyword">typedef</span> <span class="identifier">my_executor</span> <span class="identifier">executor_type</span><span class="special">;</span>
+
+ <span class="comment">// Return a custom executor implementation.</span>
+ <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">my_executor</span><span class="special">();</span>
+ <span class="special">}</span>
+
+ <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ In more complex cases, the <code class="computeroutput"><span class="identifier">associated_executor</span></code>
+ template may be partially specialised directly:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_handler</span>
<span class="special">{</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="special">};</span>
-<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
-<span class="keyword">void</span> <span class="identifier">asio_handler_invoke</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">my_handler</span><span class="special">*)</span>
-<span class="special">{</span>
- <span class="comment">// Do custom invocation here.</span>
- <span class="comment">// Default implementation calls f();</span>
-<span class="special">}</span>
+<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>
+
+ <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
+ <span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">my_handler</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
+ <span class="special">{</span>
+ <span class="comment">// Custom implementation of Executor type requirements.</span>
+ <span class="keyword">typedef</span> <span class="identifier">my_executor</span> <span class="identifier">type</span><span class="special">;</span>
+
+ <span class="comment">// Return a custom executor implementation.</span>
+ <span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">my_handler</span><span class="special">&amp;,</span>
+ <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="special">=</span> <span class="identifier">Executor</span><span class="special">())</span> <span class="keyword">noexcept</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">my_executor</span><span class="special">();</span>
+ <span class="special">}</span>
+ <span class="special">};</span>
+
+<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::asio</span>
</pre>
<p>
- The <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">strand</span><span class="special">::</span><span class="identifier">wrap</span><span class="special">()</span></code>
- function creates a new completion handler that defines <code class="computeroutput"><span class="identifier">asio_handler_invoke</span></code>
- so that the function object is executed through the strand.
+ The <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">()</span></code>
+ function is a helper to bind a specific executor object, such as a strand,
+ to a completion handler. This binding automatically associates an executor
+ as shown above. For example, to bind a strand to a completion handler we
+ would simply write:
</p>
+<pre class="programlisting"><span class="identifier">my_socket</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">my_buffer</span><span class="special">,</span>
+ <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">my_strand</span><span class="special">,</span>
+ <span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">length</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="comment">// ...</span>
+ <span class="special">}));</span>
+</pre>
<h6>
<a name="boost_asio.overview.core.strands.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.strands.see_also"></a></span><a class="link" href="strands.html#boost_asio.overview.core.strands.see_also">See
Also</a>
</h6>
<p>
- <a class="link" href="../../reference/io_service__strand.html" title="io_service::strand">io_service::strand</a>,
+ <a class="link" href="../../reference/associated_executor.html" title="associated_executor">associated_executor</a>,
+ <a class="link" href="../../reference/get_associated_executor.html" title="get_associated_executor">get_associated_executor</a>,
+ <a class="link" href="../../reference/bind_executor.html" title="bind_executor">bind_executor</a>,
+ <a class="link" href="../../reference/strand.html" title="strand">strand</a>, <a class="link" href="../../reference/io_context__strand.html" title="io_context::strand">io_context::strand</a>,
<a class="link" href="../../tutorial/tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">tutorial Timer.5</a>,
<a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.http_server_3">HTTP server
3 example</a>.
diff --git a/doc/html/boost_asio/overview/core/threads.html b/doc/html/boost_asio/overview/core/threads.html
index 039d7b0b2d..2faa780947 100644
--- a/doc/html/boost_asio/overview/core/threads.html
+++ b/doc/html/boost_asio/overview/core/threads.html
@@ -34,7 +34,7 @@
<p>
In general, it is safe to make concurrent use of distinct objects, but
unsafe to make concurrent use of a single object. However, types such as
- <code class="computeroutput"><span class="identifier">io_service</span></code> provide a stronger
+ <code class="computeroutput"><span class="identifier">io_context</span></code> provide a stronger
guarantee that it is safe to use a single object concurrently.
</p>
<h6>
@@ -43,14 +43,14 @@
Pools</a>
</h6>
<p>
- Multiple threads may call <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> to set up a pool of threads from which
+ Multiple threads may call <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> to set up a pool of threads from which
completion handlers may be invoked. This approach may also be used with
- <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">post</span><span class="special">()</span></code>
- to use a means to perform any computational tasks across a thread pool.
+ <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
+ as a means to perform arbitrary computational tasks across a thread pool.
</p>
<p>
- Note that all threads that have joined an <code class="computeroutput"><span class="identifier">io_service</span></code>'s
- pool are considered equivalent, and the <code class="computeroutput"><span class="identifier">io_service</span></code>
+ Note that all threads that have joined an <code class="computeroutput"><span class="identifier">io_context</span></code>'s
+ pool are considered equivalent, and the <code class="computeroutput"><span class="identifier">io_context</span></code>
may distribute work across them in an arbitrary fashion.
</p>
<h6>
@@ -77,7 +77,7 @@
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Asynchronous completion handlers will only be called from threads that
- are currently calling <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>.
+ are currently calling <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>.
</li></ul></div>
<p>
Consequently, it is the library user's responsibility to create and manage
@@ -88,7 +88,7 @@
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
- By only calling <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> from a single thread, the user's
+ By only calling <code class="computeroutput"><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code> from a single thread, the user's
code can avoid the development complexity associated with synchronisation.
For example, a library user can implement scalable servers that are
single-threaded (from the user's point of view).
@@ -111,7 +111,7 @@
Also</a>
</h6>
<p>
- <a class="link" href="../../reference/io_service.html" title="io_service">io_service</a>.
+ <a class="link" href="../../reference/io_context.html" title="io_context">io_context</a>, <a class="link" href="../../reference/post.html" title="post">post</a>.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>