[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,144 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Custom Memory Allocation</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="line_based.html" title="Line-Based Operations">
<link rel="next" href="handler_tracking.html" title="Handler Tracking">
</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="line_based.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="handler_tracking.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.allocation"></a><a class="link" href="allocation.html" title="Custom Memory Allocation">Custom Memory
Allocation</a>
</h4></div></div></div>
<p>
Many asynchronous operations need to allocate an object to store state
associated with the operation. For example, a Win32 implementation needs
<code class="computeroutput"><span class="identifier">OVERLAPPED</span></code>-derived objects
to pass to Win32 API functions.
</p>
<p>
Furthermore, programs typically contain easily identifiable chains of asynchronous
operations. A half duplex protocol implementation (e.g. an HTTP server)
would have a single chain of operations per client (receives followed by
sends). A full duplex protocol implementation would have two chains executing
in parallel. Programs should be able to leverage this knowledge to reuse
memory for all asynchronous operations in a chain.
</p>
<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 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="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>
The associated allocator must satisfy the standard Allocator requirements.
</p>
<p>
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">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>
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
for any new asynchronous operations started by the handler.
</p>
<p>
The custom memory allocation functions may be called from any user-created
thread that is calling a library function. The implementation guarantees
that, for the asynchronous operations included the library, the implementation
will not make concurrent calls to the memory allocation functions for that
handler. The implementation will insert appropriate memory barriers to
ensure correct memory visibility should allocation functions need to be
called from different threads.
</p>
<h6>
<a name="boost_asio.overview.core.allocation.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.allocation.see_also"></a></span><a class="link" href="allocation.html#boost_asio.overview.core.allocation.see_also">See
Also</a>
</h6>
<p>
<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>.
</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 © 2003-2021 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="line_based.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="handler_tracking.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,289 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Proactor Design Pattern: Concurrency Without Threads</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="basics.html" title="Basic Boost.Asio Anatomy">
<link rel="next" href="threads.html" title="Threads and Boost.Asio">
</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="basics.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="threads.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.async"></a><a class="link" href="async.html" title="The Proactor Design Pattern: Concurrency Without Threads">The Proactor Design
Pattern: Concurrency Without Threads</a>
</h4></div></div></div>
<p>
The Boost.Asio library offers side-by-side support for synchronous and
asynchronous operations. The asynchronous support is based on the Proactor
design pattern <a class="link" href="async.html#boost_asio.overview.core.async.references">[POSA2]</a>.
The advantages and disadvantages of this approach, when compared to a synchronous-only
or Reactor approach, are outlined below.
</p>
<h6>
<a name="boost_asio.overview.core.async.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.async.proactor_and_boost_asio"></a></span><a class="link" href="async.html#boost_asio.overview.core.async.proactor_and_boost_asio">Proactor
and Boost.Asio</a>
</h6>
<p>
Let us examine how the Proactor design pattern is implemented in Boost.Asio,
without reference to platform-specific details.
</p>
<p>
<span class="inlinemediaobject"><img src="../../proactor.png" alt="proactor"></span>
</p>
<p>
<span class="bold"><strong>Proactor design pattern (adapted from [POSA2])</strong></span>
</p>
<p>
— Asynchronous Operation
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Defines an operation that is executed asynchronously, such as an asynchronous
read or write on a socket.
</p></blockquote></div>
<p>
— Asynchronous Operation Processor
</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, internal
services like <code class="computeroutput"><span class="identifier">reactive_socket_service</span></code>
are asynchronous operation processors.
</p></blockquote></div>
<p>
— Completion Event Queue
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Buffers completion events until they are dequeued by an asynchronous
event demultiplexer.
</p></blockquote></div>
<p>
— Completion Handler
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Processes the result of an asynchronous operation. These are function
objects, often created using <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code>.
</p></blockquote></div>
<p>
— Asynchronous Event Demultiplexer
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Blocks waiting for events to occur on the completion event queue, and
returns a completed event to its caller.
</p></blockquote></div>
<p>
— Proactor
</p>
<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_context</span></code> class.
</p></blockquote></div>
<p>
— Initiator
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
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">reactive_socket_service</span></code>.
</p></blockquote></div>
<h6>
<a name="boost_asio.overview.core.async.h1"></a>
<span class="phrase"><a name="boost_asio.overview.core.async.implementation_using_reactor"></a></span><a class="link" href="async.html#boost_asio.overview.core.async.implementation_using_reactor">Implementation
Using Reactor</a>
</h6>
<p>
On many platforms, Boost.Asio implements the Proactor design pattern in
terms of a Reactor, such as <code class="computeroutput"><span class="identifier">select</span></code>,
<code class="computeroutput"><span class="identifier">epoll</span></code> or <code class="computeroutput"><span class="identifier">kqueue</span></code>. This implementation approach
corresponds to the Proactor design pattern as follows:
</p>
<p>
— Asynchronous Operation Processor
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
A reactor implemented using <code class="computeroutput"><span class="identifier">select</span></code>,
<code class="computeroutput"><span class="identifier">epoll</span></code> or <code class="computeroutput"><span class="identifier">kqueue</span></code>. When the reactor indicates
that the resource is ready to perform the operation, the processor executes
the asynchronous operation and enqueues the associated completion handler
on the completion event queue.
</p></blockquote></div>
<p>
— Completion Event Queue
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
A linked list of completion handlers (i.e. function objects).
</p></blockquote></div>
<p>
— Asynchronous Event Demultiplexer
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This is implemented by waiting on an event or condition variable until
a completion handler is available in the completion event queue.
</p></blockquote></div>
<h6>
<a name="boost_asio.overview.core.async.h2"></a>
<span class="phrase"><a name="boost_asio.overview.core.async.implementation_using_windows_overlapped_i_o"></a></span><a class="link" href="async.html#boost_asio.overview.core.async.implementation_using_windows_overlapped_i_o">Implementation
Using Windows Overlapped I/O</a>
</h6>
<p>
On Windows NT, 2000 and XP, Boost.Asio takes advantage of overlapped I/O
to provide an efficient implementation of the Proactor design pattern.
This implementation approach corresponds to the Proactor design pattern
as follows:
</p>
<p>
— Asynchronous Operation Processor
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This is implemented by the operating system. Operations are initiated
by calling an overlapped function such as <code class="computeroutput"><span class="identifier">AcceptEx</span></code>.
</p></blockquote></div>
<p>
— Completion Event Queue
</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_context</span></code> instance.
</p></blockquote></div>
<p>
— Asynchronous Event Demultiplexer
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Called by Boost.Asio to dequeue events and their associated completion
handlers.
</p></blockquote></div>
<h6>
<a name="boost_asio.overview.core.async.h3"></a>
<span class="phrase"><a name="boost_asio.overview.core.async.advantages"></a></span><a class="link" href="async.html#boost_asio.overview.core.async.advantages">Advantages</a>
</h6>
<p>
— Portability.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Many operating systems offer a native asynchronous I/O API (such as overlapped
I/O on <span class="emphasis"><em>Windows</em></span>) as the preferred option for developing
high performance network applications. The library may be implemented
in terms of native asynchronous I/O. However, if native support is not
available, the library may also be implemented using synchronous event
demultiplexors that typify the Reactor pattern, such as <span class="emphasis"><em>POSIX</em></span>
<code class="computeroutput"><span class="identifier">select</span><span class="special">()</span></code>.
</p></blockquote></div>
<p>
— Decoupling threading from concurrency.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Long-duration operations are performed asynchronously by the implementation
on behalf of the application. Consequently applications do not need to
spawn many threads in order to increase concurrency.
</p></blockquote></div>
<p>
— Performance and scalability.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Implementation strategies such as thread-per-connection (which a synchronous-only
approach would require) can degrade system performance, due to increased
context switching, synchronisation and data movement among CPUs. With
asynchronous operations it is possible to avoid the cost of context switching
by minimising the number of operating system threads — typically a limited
resource — and only activating the logical threads of control that have
events to process.
</p></blockquote></div>
<p>
— Simplified application synchronisation.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Asynchronous operation completion handlers can be written as though they
exist in a single-threaded environment, and so application logic can
be developed with little or no concern for synchronisation issues.
</p></blockquote></div>
<p>
— Function composition.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Function composition refers to the implementation of functions to provide
a higher-level operation, such as sending a message in a particular format.
Each function is implemented in terms of multiple calls to lower-level
read or write operations.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
For example, consider a protocol where each message consists of a fixed-length
header followed by a variable length body, where the length of the body
is specified in the header. A hypothetical read_message operation could
be implemented using two lower-level reads, the first to receive the
header and, once the length is known, the second to receive the body.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
To compose functions in an asynchronous model, asynchronous operations
can be chained together. That is, a completion handler for one operation
can initiate the next. Starting the first call in the chain can be encapsulated
so that the caller need not be aware that the higher-level operation
is implemented as a chain of asynchronous operations.
</p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
The ability to compose new operations in this way simplifies the development
of higher levels of abstraction above a networking library, such as functions
to support a specific protocol.
</p></blockquote></div>
<h6>
<a name="boost_asio.overview.core.async.h4"></a>
<span class="phrase"><a name="boost_asio.overview.core.async.disadvantages"></a></span><a class="link" href="async.html#boost_asio.overview.core.async.disadvantages">Disadvantages</a>
</h6>
<p>
— Program complexity.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
It is more difficult to develop applications using asynchronous mechanisms
due to the separation in time and space between operation initiation
and completion. Applications may also be harder to debug due to the inverted
flow of control.
</p></blockquote></div>
<p>
— Memory usage.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Buffer space must be committed for the duration of a read or write operation,
which may continue indefinitely, and a separate buffer is required for
each concurrent operation. The Reactor pattern, on the other hand, does
not require buffer space until a socket is ready for reading or writing.
</p></blockquote></div>
<h6>
<a name="boost_asio.overview.core.async.h5"></a>
<span class="phrase"><a name="boost_asio.overview.core.async.references"></a></span><a class="link" href="async.html#boost_asio.overview.core.async.references">References</a>
</h6>
<p>
[POSA2] D. Schmidt et al, <span class="emphasis"><em>Pattern Oriented Software Architecture,
Volume 2</em></span>. Wiley, 2000.
</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 © 2003-2021 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="basics.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="threads.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,179 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Basic Boost.Asio Anatomy</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="../core.html" title="Core Concepts and Functionality">
<link rel="next" href="async.html" title="The Proactor Design Pattern: Concurrency Without Threads">
</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="../core.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="async.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.basics"></a><a class="link" href="basics.html" title="Basic Boost.Asio Anatomy">Basic Boost.Asio Anatomy</a>
</h4></div></div></div>
<p>
Boost.Asio may be used to perform both synchronous and asynchronous operations
on I/O objects such as sockets. Before using Boost.Asio it may be useful
to get a conceptual picture of the various parts of Boost.Asio, your program,
and how they work together.
</p>
<p>
As an introductory example, let's consider what happens when you perform
a connect operation on a socket. We shall start by examining synchronous
operations.
</p>
<p>
<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>I/O execution context</strong></span>, such as an <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span></code> object, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">thread_pool</span></code>
object, or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">system_context</span></code>. This <span class="bold"><strong>I/O
execution 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_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_context</span><span class="special">);</span>
</pre>
<p>
When a synchronous connect operation is performed, the following sequence
of events occurs:
</p>
<p>
1. <span class="bold"><strong>Your program</strong></span> initiates the connect
operation by calling the <span class="bold"><strong>I/O object</strong></span>:
</p>
<pre class="programlisting"><span class="identifier">socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">server_endpoint</span><span class="special">);</span>
</pre>
<p>
2. The <span class="bold"><strong>I/O object</strong></span> forwards the request
to the <span class="bold"><strong>I/O execution context</strong></span>.
</p>
<p>
3. The <span class="bold"><strong>I/O execution 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>I/O execution context</strong></span>.
</p>
<p>
5. The <span class="bold"><strong>I/O execution 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> result means that no
error occurred). The result is then forwarded back up to the <span class="bold"><strong>I/O object</strong></span>.
</p>
<p>
6. The <span class="bold"><strong>I/O object</strong></span> throws an exception
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">system_error</span></code> if the operation failed.
If the code to initiate the operation had instead been written as:
</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">socket</span><span class="special">.</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">server_endpoint</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
then the <code class="computeroutput"><span class="identifier">error_code</span></code> variable
<code class="computeroutput"><span class="identifier">ec</span></code> would be set to the
result of the operation, and no exception would be thrown.
</p>
<p>
When an asynchronous operation is used, a different sequence of events
occurs.
</p>
<p>
<span class="inlinemediaobject"><img src="../../async_op1.png" alt="async_op1"></span>
</p>
<p>
1. <span class="bold"><strong>Your program</strong></span> initiates the connect
operation by calling the <span class="bold"><strong>I/O object</strong></span>:
</p>
<pre class="programlisting"><span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_connect</span><span class="special">(</span><span class="identifier">server_endpoint</span><span class="special">,</span> <span class="identifier">your_completion_handler</span><span class="special">);</span>
</pre>
<p>
where <code class="computeroutput"><span class="identifier">your_completion_handler</span></code>
is a function or function object with the signature:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">your_completion_handler</span><span class="special">(</span><span class="keyword">const</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">&amp;</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
The exact signature required depends on the asynchronous operation being
performed. The reference documentation indicates the appropriate form for
each operation.
</p>
<p>
2. The <span class="bold"><strong>I/O object</strong></span> forwards the request
to the <span class="bold"><strong>I/O execution context</strong></span>.
</p>
<p>
3. The <span class="bold"><strong>I/O execution context</strong></span> signals to
the <span class="bold"><strong>operating system</strong></span> that it should start
an asynchronous connect.
</p>
<p>
Time passes. (In the synchronous case this wait would have been contained
entirely within the duration of the connect operation.)
</p>
<p>
<span class="inlinemediaobject"><img src="../../async_op2.png" alt="async_op2"></span>
</p>
<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>I/O execution context</strong></span>.
</p>
<p>
5. When using an <code class="computeroutput"><span class="identifier">io_context</span></code>
as the <span class="bold"><strong>I/O execution context</strong></span>, <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 <code class="computeroutput"><span class="identifier">io_context</span></code> 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_context</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, the <span class="bold"><strong>I/O execution
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>
This is a simplified picture of how Boost.Asio operates. You will want
to delve further into the documentation if your needs are more advanced,
such as extending Boost.Asio to perform other types of asynchronous operations.
</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 © 2003-2021 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="../core.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="async.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,247 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Buffers</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="strands.html" title="Strands: Use Threads Without Explicit Locking">
<link rel="next" href="streams.html" title="Streams, Short Reads and Short Writes">
</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="strands.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="streams.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.buffers"></a><a class="link" href="buffers.html" title="Buffers">Buffers</a>
</h4></div></div></div>
<p>
Fundamentally, I/O involves the transfer of data to and from contiguous
regions of memory, called buffers. These buffers can be simply expressed
as a tuple consisting of a pointer and a size in bytes. However, to allow
the development of efficient network applications, Boost.Asio includes
support for scatter-gather operations. These operations involve one or
more buffers:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
A scatter-read receives data into multiple buffers.
</li>
<li class="listitem">
A gather-write transmits multiple buffers.
</li>
</ul></div>
<p>
Therefore we require an abstraction to represent a collection of buffers.
The approach used in Boost.Asio is to define a type (actually two types)
to represent a single buffer. These can be stored in a container, which
may be passed to the scatter-gather operations.
</p>
<p>
In addition to specifying buffers as a pointer and size in bytes, Boost.Asio
makes a distinction between modifiable memory (called mutable) and non-modifiable
memory (where the latter is created from the storage for a const-qualified
variable). These two types could therefore be defined as follows:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">*,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">mutable_buffer</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">const_buffer</span><span class="special">;</span>
</pre>
<p>
Here, a mutable_buffer would be convertible to a const_buffer, but conversion
in the opposite direction is not valid.
</p>
<p>
However, Boost.Asio does not use the above definitions as-is, but instead
defines two classes: <code class="computeroutput"><span class="identifier">mutable_buffer</span></code>
and <code class="computeroutput"><span class="identifier">const_buffer</span></code>. The goal
of these is to provide an opaque representation of contiguous memory, where:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Types behave as std::pair would in conversions. That is, a <code class="computeroutput"><span class="identifier">mutable_buffer</span></code> is convertible to
a <code class="computeroutput"><span class="identifier">const_buffer</span></code>, but
the opposite conversion is disallowed.
</li>
<li class="listitem">
There is protection against buffer overruns. Given a buffer instance,
a user can only create another buffer representing the same range of
memory or a sub-range of it. To provide further safety, the library
also includes mechanisms for automatically determining the size of
a buffer from an array, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code>
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> of POD elements, or from a
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
</li>
<li class="listitem">
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>
Finally, multiple buffers can be passed to scatter-gather operations (such
as <a class="link" href="../../reference/read.html" title="read">read()</a> or <a class="link" href="../../reference/write.html" title="write">write()</a>)
by putting the buffer objects into a container. The <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code>
and <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code>
concepts have been defined so that containers such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>,
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span></code>, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>
or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code> can be used.
</p>
<h6>
<a name="boost_asio.overview.core.buffers.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.buffers.streambuf_for_integration_with_iostreams"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.streambuf_for_integration_with_iostreams">Streambuf
for Integration with Iostreams</a>
</h6>
<p>
The class <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">basic_streambuf</span></code> is derived from <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_streambuf</span></code> to associate the input
sequence and output sequence with one or more objects of some character
array type, whose elements store arbitrary values. These character array
objects are internal to the streambuf object, but direct access to the
array elements is provided to permit them to be used with I/O operations,
such as the send or receive operations of a socket:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The input sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/data.html" title="basic_streambuf::data">data()</a>
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/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">
Data is transferred from the front of the output sequence to the back
of the input sequence by calling the <a class="link" href="../../reference/basic_streambuf/commit.html" title="basic_streambuf::commit">commit()</a>
member function.
</li>
<li class="listitem">
Data is removed from the front of the input sequence by calling the
<a class="link" href="../../reference/basic_streambuf/consume.html" title="basic_streambuf::consume">consume()</a>
member function.
</li>
</ul></div>
<p>
The streambuf constructor accepts a <code class="computeroutput"><span class="identifier">size_t</span></code>
argument specifying the maximum of the sum of the sizes of the input sequence
and output sequence. Any operation that would, if successful, grow the
internal data beyond this limit will throw a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">length_error</span></code>
exception.
</p>
<h6>
<a name="boost_asio.overview.core.buffers.h1"></a>
<span class="phrase"><a name="boost_asio.overview.core.buffers.bytewise_traversal_of_buffer_sequences"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.bytewise_traversal_of_buffer_sequences">Bytewise
Traversal of Buffer Sequences</a>
</h6>
<p>
The <code class="computeroutput"><span class="identifier">buffers_iterator</span><span class="special">&lt;&gt;</span></code>
class template allows buffer sequences (i.e. types meeting <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code> or <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code> requirements) to
be traversed as though they were a contiguous sequence of bytes. Helper
functions called buffers_begin() and buffers_end() are also provided, where
the buffers_iterator&lt;&gt; template parameter is automatically deduced.
</p>
<p>
As an example, to read a single line from a socket and into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, you may write:
</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">streambuf</span> <span class="identifier">sb</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">n</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">read_until</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">sb</span><span class="special">,</span> <span class="char">'\n'</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">streambuf</span><span class="special">::</span><span class="identifier">const_buffers_type</span> <span class="identifier">bufs</span> <span class="special">=</span> <span class="identifier">sb</span><span class="special">.</span><span class="identifier">data</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</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">buffers_begin</span><span class="special">(</span><span class="identifier">bufs</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">buffers_begin</span><span class="special">(</span><span class="identifier">bufs</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">n</span><span class="special">);</span>
</pre>
<h6>
<a name="boost_asio.overview.core.buffers.h2"></a>
<span class="phrase"><a name="boost_asio.overview.core.buffers.buffer_debugging"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.buffer_debugging">Buffer
Debugging</a>
</h6>
<p>
Some standard library implementations, such as the one that ships with
Microsoft Visual C++ 8.0 and later, provide a feature called iterator debugging.
What this means is that the validity of iterators is checked at runtime.
If a program tries to use an iterator that has been invalidated, an assertion
will be triggered. For example:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">(</span><span class="number">1</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">clear</span><span class="special">();</span> <span class="comment">// invalidates iterators</span>
<span class="special">*</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// assertion!</span>
</pre>
<p>
Boost.Asio takes advantage of this feature to add buffer debugging. Consider
the following code:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">dont_do_this</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"Hello, world!"</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">async_write</span><span class="special">(</span><span class="identifier">sock</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">msg</span><span class="special">),</span> <span class="identifier">my_handler</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
When you call an asynchronous read or write you need to ensure that the
buffers for the operation are valid until the completion handler is called.
In the above example, the buffer is the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
variable <code class="computeroutput"><span class="identifier">msg</span></code>. This variable
is on the stack, and so it goes out of scope before the asynchronous operation
completes. If you're lucky then the application will crash, but random
failures are more likely.
</p>
<p>
When buffer debugging is enabled, Boost.Asio stores an iterator into the
string until the asynchronous operation completes, and then dereferences
it to check its validity. In the above example you would observe an assertion
failure just before Boost.Asio tries to call the completion handler.
</p>
<p>
This feature is automatically made available for Microsoft Visual Studio
8.0 or later and for GCC when <code class="computeroutput"><span class="identifier">_GLIBCXX_DEBUG</span></code>
is defined. There is a performance cost to this checking, so buffer debugging
is only enabled in debug builds. For other compilers it may be enabled
by defining <code class="computeroutput"><span class="identifier">BOOST_ASIO_ENABLE_BUFFER_DEBUGGING</span></code>.
It can also be explicitly disabled by defining <code class="computeroutput"><span class="identifier">BOOST_ASIO_DISABLE_BUFFER_DEBUGGING</span></code>.
</p>
<h6>
<a name="boost_asio.overview.core.buffers.h3"></a>
<span class="phrase"><a name="boost_asio.overview.core.buffers.see_also"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/buffer.html" title="buffer">buffer</a>, <a class="link" href="../../reference/buffers_begin.html" title="buffers_begin">buffers_begin</a>,
<a class="link" href="../../reference/buffers_end.html" title="buffers_end">buffers_end</a>, <a class="link" href="../../reference/buffers_iterator.html" title="buffers_iterator">buffers_iterator</a>,
<a class="link" href="../../reference/const_buffer.html" title="const_buffer">const_buffer</a>,
<a class="link" href="../../reference/const_buffers_1.html" title="const_buffers_1">const_buffers_1</a>,
<a class="link" href="../../reference/mutable_buffer.html" title="mutable_buffer">mutable_buffer</a>,
<a class="link" href="../../reference/mutable_buffers_1.html" title="mutable_buffers_1">mutable_buffers_1</a>,
<a class="link" href="../../reference/streambuf.html" title="streambuf">streambuf</a>, <a class="link" href="../../reference/ConstBufferSequence.html" title="Constant buffer sequence requirements">ConstBufferSequence</a>,
<a class="link" href="../../reference/MutableBufferSequence.html" title="Mutable buffer sequence requirements">MutableBufferSequence</a>,
<a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.buffers">buffers example
(C++03)</a>, <a class="link" href="../../examples/cpp11_examples.html#boost_asio.examples.cpp11_examples.buffers">buffers
example (c++11)</a>.
</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 © 2003-2021 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="strands.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="streams.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,176 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<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>
— 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>
— Asynchronous resolve operations fail with <code class="computeroutput"><span class="identifier">operation_not_supported</span></code>.
</p>
<p>
— 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>
— 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 © 2003-2021 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>

View File

@@ -0,0 +1,91 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Stackless Coroutines</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="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">
<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="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">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">struct session : boost::asio::coroutine
{
boost::shared_ptr&lt;tcp::socket&gt; socket_;
boost::shared_ptr&lt;std::vector&lt;char&gt; &gt; buffer_;
session(boost::shared_ptr&lt;tcp::socket&gt; socket)
: socket_(socket),
buffer_(new std::vector&lt;char&gt;(1024))
{
}
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">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>
<span class="phrase"><a name="boost_asio.overview.core.coroutine.see_also"></a></span><a class="link" href="coroutine.html#boost_asio.overview.core.coroutine.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/coroutine.html" title="coroutine">coroutine</a>, <a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.http_server_4">HTTP Server
4 example</a>, <a class="link" href="spawn.html" title="Stackful Coroutines">Stackful
Coroutines</a>.
</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 © 2003-2021 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="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>

View File

@@ -0,0 +1,143 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Coroutines TS Support</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="spawn.html" title="Stackful Coroutines">
<link rel="next" href="../networking.html" title="Networking">
</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="spawn.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="../networking.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.coroutines_ts"></a><a class="link" href="coroutines_ts.html" title="Coroutines TS Support">Coroutines
TS Support</a>
</h4></div></div></div>
<p>
Support for the Coroutines TS is provided via the <a class="link" href="../../reference/awaitable.html" title="awaitable"><code class="computeroutput">awaitable</code></a>
class template, the <a class="link" href="../../reference/use_awaitable_t.html" title="use_awaitable_t"><code class="computeroutput">use_awaitable</code></a>
completion token, and the <a class="link" href="../../reference/co_spawn.html" title="co_spawn"><code class="computeroutput">co_spawn()</code></a>
function. These facilities allow programs to implement asynchronous logic
in a synchronous manner, in conjunction with the <code class="computeroutput">co_await</code>
keyword, as shown in the following example:
</p>
<pre class="programlisting">boost::asio::co_spawn(executor, echo(std::move(socket)), boost::asio::detached);
// ...
boost::asio::awaitable&lt;void&gt; echo(tcp::socket socket)
{
try
{
char data[1024];
for (;;)
{
std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
co_await async_write(socket, boost::asio::buffer(data, n), boost::asio::use_awaitable);
}
}
catch (std::exception&amp; e)
{
std::printf("echo Exception: %s\n", e.what());
}
}
</pre>
<p>
The first argument to <code class="computeroutput">co_spawn()</code> is an <a class="link" href="../../reference/Executor1.html" title="Executor requirements">executor</a>
that 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 an <a class="link" href="../../reference/awaitable.html" title="awaitable"><code class="computeroutput">awaitable&lt;R&gt;</code></a>,
that is the result of the coroutine's entry point function, and in the
above example is the result of the call to <code class="computeroutput">echo</code>. (Alternatively,
this argument can be a function object that returns the <a class="link" href="../../reference/awaitable.html" title="awaitable"><code class="computeroutput">awaitable&lt;R&gt;</code></a>.)
The template parameter <code class="computeroutput">R</code> is the type of return value produced
by the coroutine. In the above example, the coroutine returns <code class="computeroutput">void</code>.
</p>
<p>
The third argument is a completion token, and this is used by <code class="computeroutput">co_spawn()</code>
to produce a completion handler with signature <code class="computeroutput">void(std::exception_ptr,
R)</code>. This completion handler is invoked with the result of the coroutine
once it has finished. In the above example we pass a completion token type,
<a class="link" href="../../reference/detached.html" title="detached"><code class="computeroutput">boost::asio::detached</code></a>,
which is used to explicitly ignore the result of an asynchronous operation.
</p>
<p>
In this example the body of the coroutine is implemented in the <code class="computeroutput">echo</code>
function. When the <code class="computeroutput">use_awaitable</code> completion token is passed
to an asynchronous operation, the operation's initiating function returns
an <code class="computeroutput">awaitable</code> that may be used with the <code class="computeroutput">co_await</code>
keyword:
</p>
<pre class="programlisting">std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
</pre>
<p>
Where an asynchronous operation's handler signature has the form:
</p>
<pre class="programlisting">void handler(boost::system::error_code ec, result_type result);
</pre>
<p>
the resulting type of the <code class="computeroutput">co_await</code> expression is <code class="computeroutput">result_type</code>.
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">void handler(boost::system::error_code ec);
</pre>
<p>
the <code class="computeroutput">co_await</code> expression produces a <code class="computeroutput">void</code> result.
As above, an error is passed back to the coroutine as a <code class="computeroutput">system_error</code>
exception.
</p>
<h6>
<a name="boost_asio.overview.core.coroutines_ts.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.coroutines_ts.see_also"></a></span><a class="link" href="coroutines_ts.html#boost_asio.overview.core.coroutines_ts.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/co_spawn.html" title="co_spawn">co_spawn</a>, <a class="link" href="../../reference/detached.html" title="detached">detached</a>,
<a class="link" href="../../reference/redirect_error.html" title="redirect_error">redirect_error</a>,
<a class="link" href="../../reference/awaitable.html" title="awaitable">awaitable</a>, <a class="link" href="../../reference/use_awaitable_t.html" title="use_awaitable_t">use_awaitable_t</a>,
<a class="link" href="../../reference/use_awaitable.html" title="use_awaitable">use_awaitable</a>,
<a class="link" href="../../reference/this_coro__executor.html" title="this_coro::executor">this_coro::executor</a>,
<a class="link" href="../../examples/cpp17_examples.html#boost_asio.examples.cpp17_examples.coroutines_ts_support">Coroutines
TS examples</a>, <a class="link" href="spawn.html" title="Stackful Coroutines">Stackful
Coroutines</a>, <a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless
Coroutines</a>.
</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 © 2003-2021 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="spawn.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="../networking.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,498 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Handler Tracking</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="allocation.html" title="Custom Memory Allocation">
<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>
<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="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">
<a name="boost_asio.overview.core.handler_tracking"></a><a class="link" href="handler_tracking.html" title="Handler Tracking">Handler
Tracking</a>
</h4></div></div></div>
<p>
To aid in debugging asynchronous programs, Boost.Asio provides support
for handler tracking. When enabled by defining <code class="computeroutput"><span class="identifier">BOOST_ASIO_ENABLE_HANDLER_TRACKING</span></code>,
Boost.Asio writes debugging output to the standard error stream. The output
records asynchronous operations and the relationships between their handlers.
</p>
<p>
This feature is useful when debugging and you need to know how your asynchronous
operations are chained together, or what the pending asynchronous operations
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|1589424178.741850|0*1|signal_set@0x7ffee977d878.async_wait
@asio|1589424178.742593|0*2|socket@0x7ffee977d8a8.async_accept
@asio|1589424178.742619|.2|non_blocking_accept,ec=asio.system:11
@asio|1589424178.742625|0|resolver@0x7ffee977d760.cancel
@asio|1589424195.830382|.2|non_blocking_accept,ec=system:0
@asio|1589424195.830413|&gt;2|ec=system:0
@asio|1589424195.830473|2*3|socket@0x7fa71d808230.async_receive
@asio|1589424195.830496|.3|non_blocking_recv,ec=system:0,bytes_transferred=151
@asio|1589424195.830503|2*4|socket@0x7ffee977d8a8.async_accept
@asio|1589424195.830507|.4|non_blocking_accept,ec=asio.system:11
@asio|1589424195.830510|&lt;2|
@asio|1589424195.830529|&gt;3|ec=system:0,bytes_transferred=151
@asio|1589424195.831143|3^5|in 'async_write' (./../../../boost/asio/impl/write.hpp:330)
@asio|1589424195.831143|3*5|socket@0x7fa71d808230.async_send
@asio|1589424195.831186|.5|non_blocking_send,ec=system:0,bytes_transferred=1090
@asio|1589424195.831194|&lt;3|
@asio|1589424195.831218|&gt;5|ec=system:0,bytes_transferred=1090
@asio|1589424195.831263|5|socket@0x7fa71d808230.close
@asio|1589424195.831298|&lt;5|
@asio|1589424199.793770|&gt;1|ec=system:0,signal_number=2
@asio|1589424199.793781|1|socket@0x7ffee977d8a8.close
@asio|1589424199.793809|&lt;1|
@asio|1589424199.793840|&gt;4|ec=asio.system:125
@asio|1589424199.793854|&lt;4|
@asio|1589424199.793883|0|signal_set@0x7ffee977d878.cancel
</pre>
<p>
Each line is of the form:
</p>
<pre class="programlisting">&lt;tag&gt;|&lt;timestamp&gt;|&lt;action&gt;|&lt;description&gt;
</pre>
<p>
The <code class="computeroutput">&lt;tag&gt;</code> is always <code class="computeroutput">@asio</code>, and is used
to identify and extract the handler tracking messages from the program
output.
</p>
<p>
The <code class="computeroutput">&lt;timestamp&gt;</code> is seconds and microseconds from 1 Jan
1970 UTC.
</p>
<p>
The <code class="computeroutput">&lt;action&gt;</code> takes one of the following forms:
</p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">&gt;n</span></dt>
<dd><p>
The program entered the handler number <code class="computeroutput">n</code>. The <code class="computeroutput">&lt;description&gt;</code>
shows the arguments to the handler.
</p></dd>
<dt><span class="term">&lt;n</span></dt>
<dd><p>
The program left handler number <code class="computeroutput">n</code>.
</p></dd>
<dt><span class="term">!n</span></dt>
<dd><p>
The program left handler number n due to an exception.
</p></dd>
<dt><span class="term">~n</span></dt>
<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_context</code> is destroyed.
</p></dd>
<dt><span class="term">n^m</span></dt>
<dd><p>
The handler number <code class="computeroutput">n</code> is about to create a new asynchronous
operation with completion handler number <code class="computeroutput">m</code>. The <code class="computeroutput">&lt;description&gt;</code>
contains source location information to help identify where in the
program the asynchronous operation is being started.
</p></dd>
<dt><span class="term">n*m</span></dt>
<dd><p>
The handler number <code class="computeroutput">n</code> created a new asynchronous operation
with completion handler number <code class="computeroutput">m</code>. The <code class="computeroutput">&lt;description&gt;</code>
shows what asynchronous operation was started.
</p></dd>
<dt><span class="term">n</span></dt>
<dd><p>
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>
<p>
Where the <code class="computeroutput">&lt;description&gt;</code> shows a synchronous or asynchronous
operation, the format is <code class="computeroutput">&lt;object-type&gt;@&lt;pointer&gt;.&lt;operation&gt;</code>.
For handler entry, it shows a comma-separated list of arguments and their
values.
</p>
<p>
As shown above, Each handler is assigned a numeric identifier. Where the
handler tracking output shows a handler number of 0, it means that the
action was performed outside of any handler.
</p>
<h6>
<a name="boost_asio.overview.core.handler_tracking.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.handler_tracking.adding_location_information"></a></span><a class="link" href="handler_tracking.html#boost_asio.overview.core.handler_tracking.adding_location_information">Adding
Location Information</a>
</h6>
<p>
Programs may augment the handler tracking output's location information
by using the macro <code class="computeroutput"><span class="identifier">BOOST_ASIO_HANDLER_LOCATION</span></code>
in the source code. For example:
</p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">HANDLER_LOCATION</span> <span class="special">\</span>
<span class="identifier">BOOST_ASIO_HANDLER_LOCATION</span><span class="special">((</span><span class="identifier">__FILE__</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">,</span> <span class="identifier">__func__</span><span class="special">))</span>
<span class="comment">// ...</span>
<span class="keyword">void</span> <span class="identifier">do_read</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">HANDLER_LOCATION</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">self</span><span class="special">(</span><span class="identifier">shared_from_this</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">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">max_length</span><span class="special">),</span>
<span class="special">[</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">self</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">std</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="identifier">HANDLER_LOCATION</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="special">{</span>
<span class="identifier">do_write</span><span class="special">(</span><span class="identifier">length</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">});</span>
<span class="special">}</span>
</pre>
<p>
With the additional location information available, the handler tracking
output may include a call stack of source locations:
</p>
<pre class="programlisting">@asio|1589423304.861944|&gt;7|ec=system:0,bytes_transferred=5
@asio|1589423304.861952|7^8|in 'async_write' (./../../../boost/asio/impl/write.hpp:330)
@asio|1589423304.861952|7^8|called from 'do_write' (handler_tracking/async_tcp_echo_server.cpp:62)
@asio|1589423304.861952|7^8|called from 'operator()' (handler_tracking/async_tcp_echo_server.cpp:51)
@asio|1589423304.861952|7*8|socket@0x7ff61c008230.async_send
@asio|1589423304.861975|.8|non_blocking_send,ec=system:0,bytes_transferred=5
@asio|1589423304.861980|&lt;7|
</pre>
<p>
Furthermore, if <code class="computeroutput">std::source_location</code> or <code class="computeroutput">std::experimental::source_location</code>
are available, the <a class="link" href="../../reference/use_awaitable_t.html" title="use_awaitable_t"><code class="computeroutput">use_awaitable_t</code></a>
token (when default-constructed or used as a default completion token)
will also cause handler tracking to output a source location for each newly
created asynchronous operation. A <code class="computeroutput">use_awaitable_t</code> object may
also be explicitly constructed with location information.
</p>
<h6>
<a name="boost_asio.overview.core.handler_tracking.h1"></a>
<span class="phrase"><a name="boost_asio.overview.core.handler_tracking.visual_representations"></a></span><a class="link" href="handler_tracking.html#boost_asio.overview.core.handler_tracking.visual_representations">Visual
Representations</a>
</h6>
<p>
The handler tracking output may be post-processed using the included <code class="literal">handlerviz.pl</code>
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.h2"></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_LOCATION</span><span class="special">(</span><span class="identifier">args</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
A variable declaration that is used to define a source code location.
<code class="computeroutput"><span class="identifier">args</span></code> is a parenthesised
function argument list containing the file name, line number,
and function name.
</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.h3"></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">Handler
tracking examples</a>.
</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 © 2003-2021 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="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>

View File

@@ -0,0 +1,165 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Line-Based Operations</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="reactor.html" title="Reactor-Style Operations">
<link rel="next" href="allocation.html" title="Custom Memory Allocation">
</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="reactor.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="allocation.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.line_based"></a><a class="link" href="line_based.html" title="Line-Based Operations">Line-Based Operations</a>
</h4></div></div></div>
<p>
Many commonly-used internet protocols are line-based, which means that
they have protocol elements that are delimited by the character sequence
<code class="computeroutput"><span class="string">"\r\n"</span></code>. Examples
include HTTP, SMTP and FTP. To more easily permit the implementation of
line-based protocols, as well as other protocols that use delimiters, Boost.Asio
includes the functions <code class="computeroutput"><span class="identifier">read_until</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>.
</p>
<p>
The following example illustrates the use of <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code> in an HTTP server, to receive the first
line of an HTTP request from a client:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">http_connection</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="keyword">void</span> <span class="identifier">start</span><span class="special">()</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">async_read_until</span><span class="special">(</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">data_</span><span class="special">,</span> <span class="string">"\r\n"</span><span class="special">,</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">http_connection</span><span class="special">::</span><span class="identifier">handle_request_line</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">));</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">handle_request_line</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>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">method</span><span class="special">,</span> <span class="identifier">uri</span><span class="special">,</span> <span class="identifier">version</span><span class="special">;</span>
<span class="keyword">char</span> <span class="identifier">sp1</span><span class="special">,</span> <span class="identifier">sp2</span><span class="special">,</span> <span class="identifier">cr</span><span class="special">,</span> <span class="identifier">lf</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span> <span class="identifier">is</span><span class="special">(&amp;</span><span class="identifier">data_</span><span class="special">);</span>
<span class="identifier">is</span><span class="special">.</span><span class="identifier">unsetf</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">skipws</span><span class="special">);</span>
<span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">method</span> <span class="special">&gt;&gt;</span> <span class="identifier">sp1</span> <span class="special">&gt;&gt;</span> <span class="identifier">uri</span> <span class="special">&gt;&gt;</span> <span class="identifier">sp2</span> <span class="special">&gt;&gt;</span> <span class="identifier">version</span> <span class="special">&gt;&gt;</span> <span class="identifier">cr</span> <span class="special">&gt;&gt;</span> <span class="identifier">lf</span><span class="special">;</span>
<span class="special">...</span>
<span class="special">}</span>
<span class="special">}</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">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">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span> <span class="identifier">data_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">streambuf</span></code> data member
serves as a place to store the data that has been read from the socket
before it is searched for the delimiter. It is important to remember that
there may be additional data <span class="emphasis"><em>after</em></span> the delimiter.
This surplus data should be left in the <code class="computeroutput"><span class="identifier">streambuf</span></code>
so that it may be inspected by a subsequent call to <code class="computeroutput"><span class="identifier">read_until</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>.
</p>
<p>
The delimiters may be specified as a single <code class="computeroutput"><span class="keyword">char</span></code>,
a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> or a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">regex</span></code>.
The <code class="computeroutput"><span class="identifier">read_until</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>
functions also include overloads that accept a user-defined function object
called a match condition. For example, to read data into a streambuf until
whitespace is encountered:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffers_iterator</span><span class="special">&lt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span><span class="special">::</span><span class="identifier">const_buffers_type</span><span class="special">&gt;</span> <span class="identifier">iterator</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">iterator</span><span class="special">,</span> <span class="keyword">bool</span><span class="special">&gt;</span>
<span class="identifier">match_whitespace</span><span class="special">(</span><span class="identifier">iterator</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">iterator</span> <span class="identifier">end</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">begin</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">)</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">isspace</span><span class="special">(*</span><span class="identifier">i</span><span class="special">++))</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">false</span><span class="special">);</span>
<span class="special">}</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">streambuf</span> <span class="identifier">b</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">read_until</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">match_whitespace</span><span class="special">);</span>
</pre>
<p>
To read data into a streambuf until a matching character is found:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">match_char</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">explicit</span> <span class="identifier">match_char</span><span class="special">(</span><span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">c_</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">bool</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()(</span>
<span class="identifier">Iterator</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">end</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
<span class="identifier">Iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">begin</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">)</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">c_</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">i</span><span class="special">++)</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="keyword">false</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">char</span> <span class="identifier">c_</span><span class="special">;</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;&gt;</span> <span class="keyword">struct</span> <span class="identifier">is_match_condition</span><span class="special">&lt;</span><span class="identifier">match_char</span><span class="special">&gt;</span>
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
<span class="special">}</span> <span class="special">}</span> <span class="comment">// namespace boost::asio</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">streambuf</span> <span class="identifier">b</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">read_until</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">match_char</span><span class="special">(</span><span class="char">'a'</span><span class="special">));</span>
</pre>
<p>
The <code class="computeroutput"><span class="identifier">is_match_condition</span><span class="special">&lt;&gt;</span></code> type trait automatically evaluates
to true for functions, and for function objects with a nested <code class="computeroutput"><span class="identifier">result_type</span></code> typedef. For other types
the trait must be explicitly specialised, as shown above.
</p>
<h6>
<a name="boost_asio.overview.core.line_based.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.line_based.see_also"></a></span><a class="link" href="line_based.html#boost_asio.overview.core.line_based.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/async_read_until.html" title="async_read_until">async_read_until()</a>,
<a class="link" href="../../reference/is_match_condition.html" title="is_match_condition">is_match_condition</a>,
<a class="link" href="../../reference/read_until.html" title="read_until">read_until()</a>, <a class="link" href="../../reference/streambuf.html" title="streambuf">streambuf</a>, <a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.http_client">HTTP
client example</a>.
</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 © 2003-2021 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="reactor.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="allocation.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,87 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Reactor-Style Operations</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="streams.html" title="Streams, Short Reads and Short Writes">
<link rel="next" href="line_based.html" title="Line-Based Operations">
</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="streams.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="line_based.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.reactor"></a><a class="link" href="reactor.html" title="Reactor-Style Operations">Reactor-Style Operations</a>
</h4></div></div></div>
<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 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_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_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>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</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="identifier">buf</span><span class="special">(</span><span class="identifier">socket</span><span class="special">.</span><span class="identifier">available</span><span class="special">());</span>
<span class="identifier">socket</span><span class="special">.</span><span class="identifier">read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">buf</span><span class="special">));</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
These operations are supported for sockets on all platforms, and for the
POSIX stream-oriented descriptor classes.
</p>
<h6>
<a name="boost_asio.overview.core.reactor.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.reactor.see_also"></a></span><a class="link" href="reactor.html#boost_asio.overview.core.reactor.see_also">See
Also</a>
</h6>
<p>
<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
example</a>.
</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 © 2003-2021 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="streams.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="line_based.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,154 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Stackful Coroutines</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="coroutine.html" title="Stackless Coroutines">
<link rel="next" href="coroutines_ts.html" title="Coroutines TS Support">
</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="coroutine.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="coroutines_ts.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.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">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">boost::asio::spawn(my_strand, do_echo);
// ...
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);
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">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">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">yield</code> may be passed to an asynchronous operation in place
of the completion handler, as in:
</p>
<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
coroutine will be resumed automatically when the asynchronous operation
completes.
</p>
<p>
Where an asynchronous operation's handler signature has the form:
</p>
<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">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">void handler(boost::system::error_code ec);
</pre>
<p>
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">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">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">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">void coroutine(boost::asio::basic_yield_context&lt;Handler&gt; yield);
</pre>
<h6>
<a name="boost_asio.overview.core.spawn.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.spawn.see_also"></a></span><a class="link" href="spawn.html#boost_asio.overview.core.spawn.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/spawn.html" title="spawn">spawn</a>, <a class="link" href="../../reference/yield_context.html" title="yield_context">yield_context</a>,
<a class="link" href="../../reference/basic_yield_context.html" title="basic_yield_context">basic_yield_context</a>,
<a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.spawn">Spawn example
(C++03)</a>, <a class="link" href="../../examples/cpp11_examples.html#boost_asio.examples.cpp11_examples.spawn">Spawn
example (C++11)</a>, <a class="link" href="coroutine.html" title="Stackless Coroutines">Stackless
Coroutines</a>.
</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 © 2003-2021 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="coroutine.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="coroutines_ts.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,171 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Strands: Use Threads Without Explicit Locking</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="threads.html" title="Threads and Boost.Asio">
<link rel="next" href="buffers.html" title="Buffers">
</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="threads.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="buffers.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.strands"></a><a class="link" href="strands.html" title="Strands: Use Threads Without Explicit Locking">Strands: Use Threads
Without Explicit Locking</a>
</h4></div></div></div>
<p>
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).
</p>
<p>
Strands may be either implicit or explicit, as illustrated by the following
alternative approaches:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
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">
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.
</li>
<li class="listitem">
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>
In the case of composed asynchronous operations, such as <code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code>
or <code class="computeroutput"><span class="identifier">async_read_until</span><span class="special">()</span></code>,
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 <code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code> it's the socket, which the caller can
<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">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">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/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>.
</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 © 2003-2021 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="threads.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="buffers.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,128 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Streams, Short Reads and Short Writes</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="buffers.html" title="Buffers">
<link rel="next" href="reactor.html" title="Reactor-Style Operations">
</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="buffers.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="reactor.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.streams"></a><a class="link" href="streams.html" title="Streams, Short Reads and Short Writes">Streams, Short Reads
and Short Writes</a>
</h4></div></div></div>
<p>
Many I/O objects in Boost.Asio are stream-oriented. This means that:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
There are no message boundaries. The data being transferred is a continuous
sequence of bytes.
</li>
<li class="listitem">
Read or write operations may transfer fewer bytes than requested. This
is referred to as a short read or short write.
</li>
</ul></div>
<p>
Objects that provide stream-oriented I/O model one or more of the following
type requirements:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">SyncReadStream</span></code>, where
synchronous read operations are performed using a member function called
<code class="computeroutput"><span class="identifier">read_some</span><span class="special">()</span></code>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">AsyncReadStream</span></code>, where
asynchronous read operations are performed using a member function
called <code class="computeroutput"><span class="identifier">async_read_some</span><span class="special">()</span></code>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">SyncWriteStream</span></code>, where
synchronous write operations are performed using a member function
called <code class="computeroutput"><span class="identifier">write_some</span><span class="special">()</span></code>.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">AsyncWriteStream</span></code>, where
asynchronous write operations are performed using a member function
called <code class="computeroutput"><span class="identifier">async_write_some</span><span class="special">()</span></code>.
</li>
</ul></div>
<p>
Examples of stream-oriented I/O objects include <code class="computeroutput"><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code>,
<code class="computeroutput"><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;&gt;</span></code>,
<code class="computeroutput"><span class="identifier">posix</span><span class="special">::</span><span class="identifier">stream_descriptor</span></code>, <code class="computeroutput"><span class="identifier">windows</span><span class="special">::</span><span class="identifier">stream_handle</span></code>,
etc.
</p>
<p>
Programs typically want to transfer an exact number of bytes. When a short
read or short write occurs the program must restart the operation, and
continue to do so until the required number of bytes has been transferred.
Boost.Asio provides generic functions that do this automatically: <code class="computeroutput"><span class="identifier">read</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">async_read</span><span class="special">()</span></code>,
<code class="computeroutput"><span class="identifier">write</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">async_write</span><span class="special">()</span></code>.
</p>
<h6>
<a name="boost_asio.overview.core.streams.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.streams.why_eof_is_an_error"></a></span><a class="link" href="streams.html#boost_asio.overview.core.streams.why_eof_is_an_error">Why EOF
is an Error</a>
</h6>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The end of a stream can cause <code class="computeroutput"><span class="identifier">read</span></code>,
<code class="computeroutput"><span class="identifier">async_read</span></code>, <code class="computeroutput"><span class="identifier">read_until</span></code> or <code class="computeroutput"><span class="identifier">async_read_until</span></code>
functions to violate their contract. E.g. a read of N bytes may finish
early due to EOF.
</li>
<li class="listitem">
An EOF error may be used to distinguish the end of a stream from a
successful read of size 0.
</li>
</ul></div>
<h6>
<a name="boost_asio.overview.core.streams.h1"></a>
<span class="phrase"><a name="boost_asio.overview.core.streams.see_also"></a></span><a class="link" href="streams.html#boost_asio.overview.core.streams.see_also">See
Also</a>
</h6>
<p>
<a class="link" href="../../reference/async_read.html" title="async_read">async_read()</a>, <a class="link" href="../../reference/async_write.html" title="async_write">async_write()</a>, <a class="link" href="../../reference/read.html" title="read">read()</a>, <a class="link" href="../../reference/write.html" title="write">write()</a>,
<a class="link" href="../../reference/AsyncReadStream.html" title="Buffer-oriented asynchronous read stream requirements">AsyncReadStream</a>,
<a class="link" href="../../reference/AsyncWriteStream.html" title="Buffer-oriented asynchronous write stream requirements">AsyncWriteStream</a>,
<a class="link" href="../../reference/SyncReadStream.html" title="Buffer-oriented synchronous read stream requirements">SyncReadStream</a>,
<a class="link" href="../../reference/SyncWriteStream.html" title="Buffer-oriented synchronous write stream requirements">SyncWriteStream</a>.
</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 © 2003-2021 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="buffers.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="reactor.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,131 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Threads and Boost.Asio</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="async.html" title="The Proactor Design Pattern: Concurrency Without Threads">
<link rel="next" href="strands.html" title="Strands: Use Threads Without Explicit Locking">
</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="async.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="strands.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.threads"></a><a class="link" href="threads.html" title="Threads and Boost.Asio">Threads and Boost.Asio</a>
</h4></div></div></div>
<h6>
<a name="boost_asio.overview.core.threads.h0"></a>
<span class="phrase"><a name="boost_asio.overview.core.threads.thread_safety"></a></span><a class="link" href="threads.html#boost_asio.overview.core.threads.thread_safety">Thread
Safety</a>
</h6>
<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_context</span></code> provide a stronger
guarantee that it is safe to use a single object concurrently.
</p>
<h6>
<a name="boost_asio.overview.core.threads.h1"></a>
<span class="phrase"><a name="boost_asio.overview.core.threads.thread_pools"></a></span><a class="link" href="threads.html#boost_asio.overview.core.threads.thread_pools">Thread
Pools</a>
</h6>
<p>
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">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_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>
<a name="boost_asio.overview.core.threads.h2"></a>
<span class="phrase"><a name="boost_asio.overview.core.threads.internal_threads"></a></span><a class="link" href="threads.html#boost_asio.overview.core.threads.internal_threads">Internal
Threads</a>
</h6>
<p>
The implementation of this library for a particular platform may make use
of one or more internal threads to emulate asynchronicity. As far as possible,
these threads must be invisible to the library user. In particular, the
threads:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
must not call the user's code directly; and
</li>
<li class="listitem">
must block all signals.
</li>
</ul></div>
<p>
This approach is complemented by the following guarantee:
</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_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
all threads to which the notifications will be delivered.
</p>
<p>
The reasons for this approach include:
</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_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).
</li>
<li class="listitem">
A library user may need to perform initialisation in a thread shortly
after the thread starts and before any other application code is executed.
For example, users of Microsoft's COM must call <code class="computeroutput"><span class="identifier">CoInitializeEx</span></code>
before any other COM operations can be called from that thread.
</li>
<li class="listitem">
The library interface is decoupled from interfaces for thread creation
and management, and permits implementations on platforms where threads
are not available.
</li>
</ul></div>
<h6>
<a name="boost_asio.overview.core.threads.h3"></a>
<span class="phrase"><a name="boost_asio.overview.core.threads.see_also"></a></span><a class="link" href="threads.html#boost_asio.overview.core.threads.see_also">See
Also</a>
</h6>
<p>
<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>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2003-2021 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="async.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="strands.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>