]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/doc/html/fiber/when_any/when_any/when_any__simple_completion.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / doc / html / fiber / when_any / when_any / when_any__simple_completion.html
CommitLineData
7c673cae
FG
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4<title>when_any, simple completion</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
7<link rel="home" href="../../../index.html" title="Chapter&#160;1.&#160;Fiber">
8<link rel="up" href="../when_any.html" title="when_any">
9<link rel="prev" href="../when_any.html" title="when_any">
10<link rel="next" href="when_any__return_value.html" title="when_any, return value">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="../when_any.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../when_any.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="when_any__return_value.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h4 class="title">
27<a name="fiber.when_any.when_any.when_any__simple_completion"></a><a name="wait_first_simple_section"></a><a class="link" href="when_any__simple_completion.html" title="when_any, simple completion">when_any,
28 simple completion</a>
29</h4></div></div></div>
30<p>
31 The simplest case is when you only need to know that the first of a set
32 of asynchronous tasks has completed &#8212; but you don't need to obtain a return
33 value, and you're confident that they will not throw exceptions.
34 </p>
35<p>
36 <a name="wait_done"></a>For this we introduce a <code class="computeroutput"><span class="identifier">Done</span></code>
37 class to wrap a <code class="computeroutput"><span class="keyword">bool</span></code> variable
38 with a <a class="link" href="../../synchronization/conditions.html#class_condition_variable"><code class="computeroutput">condition_variable</code></a> and a <a class="link" href="../../synchronization/mutex_types.html#class_mutex"><code class="computeroutput">mutex</code></a>:
39 </p>
40<p>
41</p>
42<pre class="programlisting"><span class="comment">// Wrap canonical pattern for condition_variable + bool flag</span>
43<span class="keyword">struct</span> <span class="identifier">Done</span> <span class="special">{</span>
44<span class="keyword">private</span><span class="special">:</span>
45 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">cond</span><span class="special">;</span>
46 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mutex</span><span class="special">;</span>
47 <span class="keyword">bool</span> <span class="identifier">ready</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
48
49<span class="keyword">public</span><span class="special">:</span>
50 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">Done</span> <span class="special">&gt;</span> <span class="identifier">ptr</span><span class="special">;</span>
51
52 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">()</span> <span class="special">{</span>
53 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span> <span class="identifier">mutex</span><span class="special">);</span>
54 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lock</span><span class="special">,</span> <span class="special">[</span><span class="keyword">this</span><span class="special">](){</span> <span class="keyword">return</span> <span class="identifier">ready</span><span class="special">;</span> <span class="special">});</span>
55 <span class="special">}</span>
56
57 <span class="keyword">void</span> <span class="identifier">notify</span><span class="special">()</span> <span class="special">{</span>
58 <span class="special">{</span>
59 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span> <span class="identifier">mutex</span><span class="special">);</span>
60 <span class="identifier">ready</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
61 <span class="special">}</span> <span class="comment">// release mutex</span>
62 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">notify_one</span><span class="special">();</span>
63 <span class="special">}</span>
64<span class="special">};</span>
65</pre>
66<p>
67 </p>
68<p>
69 The pattern we follow throughout this section is to pass a <a href="http://www.cplusplus.com/reference/memory/shared_ptr/" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;&gt;</span></code></a>
70 to the relevant synchronization object to the various tasks' fiber functions.
71 This eliminates nagging questions about the lifespan of the synchronization
72 object relative to the last of the fibers.
73 </p>
74<p>
75 <a name="wait_first_simple"></a><code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code> uses that tactic for <a class="link" href="when_any__simple_completion.html#wait_done"><code class="computeroutput"><span class="identifier">Done</span></code></a>:
76 </p>
77<p>
78</p>
79<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
80<span class="keyword">void</span> <span class="identifier">wait_first_simple</span><span class="special">(</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
81 <span class="comment">// Use shared_ptr because each function's fiber will bind it separately,</span>
82 <span class="comment">// and we're going to return before the last of them completes.</span>
83 <span class="keyword">auto</span> <span class="identifier">done</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">Done</span> <span class="special">&gt;()</span> <span class="special">);</span>
84 <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">done</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
85 <span class="identifier">done</span><span class="special">-&gt;</span><span class="identifier">wait</span><span class="special">();</span>
86<span class="special">}</span>
87</pre>
88<p>
89 </p>
90<p>
91 <a name="wait_first_simple_impl"></a><code class="computeroutput"><span class="identifier">wait_first_simple_impl</span><span class="special">()</span></code> is an ordinary recursion over the argument
92 pack, capturing <code class="computeroutput"><span class="identifier">Done</span><span class="special">::</span><span class="identifier">ptr</span></code> for each new fiber:
93 </p>
94<p>
95</p>
96<pre class="programlisting"><span class="comment">// Degenerate case: when there are no functions to wait for, return</span>
97<span class="comment">// immediately.</span>
98<span class="keyword">void</span> <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">Done</span><span class="special">::</span><span class="identifier">ptr</span><span class="special">)</span> <span class="special">{</span>
99<span class="special">}</span>
100
101<span class="comment">// When there's at least one function to wait for, launch it and recur to</span>
102<span class="comment">// process the rest.</span>
103<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
104<span class="keyword">void</span> <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">Done</span><span class="special">::</span><span class="identifier">ptr</span> <span class="identifier">done</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
105 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span> <span class="special">[</span><span class="identifier">done</span><span class="special">,</span> <span class="identifier">function</span><span class="special">](){</span>
106 <span class="identifier">function</span><span class="special">();</span>
107 <span class="identifier">done</span><span class="special">-&gt;</span><span class="identifier">notify</span><span class="special">();</span>
108 <span class="special">}).</span><span class="identifier">detach</span><span class="special">();</span>
109 <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">done</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
110<span class="special">}</span>
111</pre>
112<p>
113 </p>
114<p>
115 The body of the fiber's lambda is extremely simple, as promised: call the
116 function, notify <a class="link" href="when_any__simple_completion.html#wait_done"><code class="computeroutput"><span class="identifier">Done</span></code></a>
117 when it returns. The first fiber to do so allows <code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code> to return &#8212; which is why it's useful to
118 have <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">Done</span><span class="special">&gt;</span></code>
119 manage the lifespan of our <code class="computeroutput"><span class="identifier">Done</span></code>
120 object rather than declaring it as a stack variable in <code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code>.
121 </p>
122<p>
123 This is how you might call it:
124 </p>
125<p>
126</p>
127<pre class="programlisting"><span class="identifier">wait_first_simple</span><span class="special">(</span>
128 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_long"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
129 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_medium"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
130 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_short"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
131</pre>
132<p>
133 </p>
134<p>
135 In this example, control resumes after <code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code> when <a class="link" href="../../when_any.html#wait_sleeper"><code class="computeroutput"><span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_short"</span><span class="special">,</span>
136 <span class="number">50</span><span class="special">)</span></code></a>
137 completes &#8212; even though the other two <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code> fibers are still running.
138 </p>
139</div>
140<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
141<td align="left"></td>
142<td align="right"><div class="copyright-footer">Copyright &#169; 2013 Oliver Kowalke<p>
143 Distributed under the Boost Software License, Version 1.0. (See accompanying
144 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>)
145 </p>
146</div></td>
147</tr></table>
148<hr>
149<div class="spirit-nav">
150<a accesskey="p" href="../when_any.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../when_any.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="when_any__return_value.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
151</div>
152</body>
153</html>