Insane_DNS/libraries/asio-1.28.1/doc/asio/reference/experimental__co_composed.html

191 lines
20 KiB
HTML
Raw Normal View History

2023-10-24 21:59:30 -04:00
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>experimental::co_composed</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../reference.html" title="Reference">
<link rel="prev" href="experimental__channel_traits__rebind/other.html" title="experimental::channel_traits::rebind::other">
<link rel="next" href="experimental__co_spawn.html" title="experimental::co_spawn">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="experimental__channel_traits__rebind/other.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="experimental__co_spawn.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.reference.experimental__co_composed"></a><a class="link" href="experimental__co_composed.html" title="experimental::co_composed">experimental::co_composed</a>
</h3></div></div></div>
<p>
<a class="indexterm" name="asio.indexterm.experimental__co_composed"></a>
</p>
<p>
Creates an initiation function object that may be used to launch a coroutine-based
composed asynchronous operation.
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
<span class="identifier">completion_signature</span><span class="special">...</span> <span class="identifier">Signatures</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Implementation</span><span class="special">,</span>
<span class="keyword">typename</span><span class="special">...</span> <span class="identifier">IoObjectsOrExecutors</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">co_composed</span><span class="special">(</span>
<span class="identifier">Implementation</span> <span class="special">&amp;&amp;</span> <span class="identifier">implementation</span><span class="special">,</span>
<span class="identifier">IoObjectsOrExecutors</span> <span class="special">&amp;&amp;...</span> <span class="identifier">io_objects_or_executors</span><span class="special">);</span>
</pre>
<p>
The <a class="link" href="experimental__co_composed.html" title="experimental::co_composed"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">co_composed</span></code></a> utility simplifies the
implementation of composed asynchronous operations by automatically adapting
a coroutine to be an initiation function object for use with <code class="computeroutput"><span class="identifier">async_initiate</span></code>. When awaiting asynchronous
operations, the coroutine automatically uses a conforming intermediate completion
handler.
</p>
<h5>
<a name="asio.reference.experimental__co_composed.h0"></a>
<span><a name="asio.reference.experimental__co_composed.parameters"></a></span><a class="link" href="experimental__co_composed.html#asio.reference.experimental__co_composed.parameters">Parameters</a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">implementation</span></dt>
<dd><p>
A function object that contains the coroutine-based implementation
of the composed asynchronous operation. The first argument to the function
object represents the state of the operation, and may be used to test
for cancellation. The remaining arguments are those passed to <code class="computeroutput"><span class="identifier">async_initiate</span></code> after the completion
token.
</p></dd>
<dt><span class="term">io_objects_or_executors</span></dt>
<dd><p>
Zero or more I/O objects or I/O executors for which outstanding work
must be maintained while the operation is incomplete.
</p></dd>
</dl>
</div>
<h5>
<a name="asio.reference.experimental__co_composed.h1"></a>
<span><a name="asio.reference.experimental__co_composed.per_operation_cancellation"></a></span><a class="link" href="experimental__co_composed.html#asio.reference.experimental__co_composed.per_operation_cancellation">Per-Operation
Cancellation</a>
</h5>
<p>
By default, per-operation cancellation is disabled for composed operations
that use <a class="link" href="experimental__co_composed.html" title="experimental::co_composed"><code class="computeroutput"><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">co_composed</span></code></a>. It must be explicitly
enabled by calling the state's <code class="computeroutput"><span class="identifier">reset_cancellation_state</span></code>
function.
</p>
<h5>
<a name="asio.reference.experimental__co_composed.h2"></a>
<span><a name="asio.reference.experimental__co_composed.examples"></a></span><a class="link" href="experimental__co_composed.html#asio.reference.experimental__co_composed.examples">Examples</a>
</h5>
<p>
The following example illustrates manual error handling and explicit checks
for cancellation. The completion handler is invoked via a <code class="computeroutput"><span class="identifier">co_yield</span></code>
to the state's <code class="computeroutput"><span class="identifier">complete</span></code> function,
which never returns.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special">&lt;</span>
<span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">co_composed</span><span class="special">(</span>
<span class="special">[](</span><span class="keyword">auto</span> <span class="identifier">state</span><span class="special">,</span> <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">)</span> <span class="special">-&gt;</span> <span class="keyword">void</span>
<span class="special">{</span>
<span class="identifier">state</span><span class="special">.</span><span class="identifier">reset_cancellation_state</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">enable_terminal_cancellation</span><span class="special">());</span>
<span class="keyword">while</span> <span class="special">(!</span><span class="identifier">state</span><span class="special">.</span><span class="identifier">cancelled</span><span class="special">())</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="keyword">auto</span> <span class="special">[</span><span class="identifier">e1</span><span class="special">,</span> <span class="identifier">n1</span><span class="special">]</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</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">asio</span><span class="special">::</span><span class="identifier">as_tuple</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">));</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">e1</span><span class="special">)</span>
<span class="identifier">co_yield</span> <span class="identifier">state</span><span class="special">.</span><span class="identifier">complete</span><span class="special">(</span><span class="identifier">e1</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!!</span><span class="identifier">state</span><span class="special">.</span><span class="identifier">cancelled</span><span class="special">())</span>
<span class="identifier">co_yield</span> <span class="identifier">state</span><span class="special">.</span><span class="identifier">complete</span><span class="special">(</span>
<span class="identifier">make_error_code</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">error</span><span class="special">::</span><span class="identifier">operation_aborted</span><span class="special">));</span>
<span class="keyword">auto</span> <span class="special">[</span><span class="identifier">e2</span><span class="special">,</span> <span class="identifier">n2</span><span class="special">]</span> <span class="special">=</span>
<span class="identifier">co_await</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">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">n1</span><span class="special">),</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">as_tuple</span><span class="special">(</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">));</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">e2</span><span class="special">)</span>
<span class="identifier">co_yield</span> <span class="identifier">state</span><span class="special">.</span><span class="identifier">complete</span><span class="special">(</span><span class="identifier">e2</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">},</span> <span class="identifier">socket</span><span class="special">),</span>
<span class="identifier">token</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">socket</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
This next example shows exception-based error handling and implicit checks
for cancellation. The completion handler is invoked after returning from
the coroutine via <code class="computeroutput"><span class="identifier">co_return</span></code>.
Valid <code class="computeroutput"><span class="identifier">co_return</span></code> values are
specified using completion signatures passed to the <code class="computeroutput"><span class="identifier">co_composed</span></code>
function.
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_echo</span><span class="special">(</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special">&lt;</span>
<span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)&gt;(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">co_composed</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">error_code</span><span class="special">)&gt;(</span>
<span class="special">[](</span><span class="keyword">auto</span> <span class="identifier">state</span><span class="special">,</span> <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">socket</span><span class="special">)</span> <span class="special">-&gt;</span> <span class="keyword">void</span>
<span class="special">{</span>
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">state</span><span class="special">.</span><span class="identifier">throw_if_cancelled</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>
<span class="identifier">state</span><span class="special">.</span><span class="identifier">reset_cancellation_state</span><span class="special">(</span>
<span class="identifier">asio</span><span class="special">::</span><span class="identifier">enable_terminal_cancellation</span><span class="special">());</span>
<span class="keyword">for</span> <span class="special">(;;)</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1024</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">co_await</span> <span class="identifier">socket</span><span class="special">.</span><span class="identifier">async_read_some</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">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="identifier">co_await</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span>
<span class="identifier">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">n</span><span class="special">),</span> <span class="identifier">asio</span><span class="special">::</span><span class="identifier">deferred</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">system_error</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">co_return</span> <span class="special">{</span><span class="identifier">e</span><span class="special">.</span><span class="identifier">code</span><span class="special">()};</span>
<span class="special">}</span>
<span class="special">},</span> <span class="identifier">socket</span><span class="special">),</span>
<span class="identifier">token</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">socket</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<h5>
<a name="asio.reference.experimental__co_composed.h3"></a>
<span><a name="asio.reference.experimental__co_composed.requirements"></a></span><a class="link" href="experimental__co_composed.html#asio.reference.experimental__co_composed.requirements">Requirements</a>
</h5>
<p>
<span class="emphasis"><em>Header: </em></span><code class="literal">asio/experimental/co_composed.hpp</code>
</p>
<p>
<span class="emphasis"><em>Convenience header: </em></span>None
</p>
</div>
<div class="copyright-footer">Copyright © 2003-2023 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>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="experimental__channel_traits__rebind/other.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="experimental__co_spawn.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>