]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/doc/barrier.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / doc / barrier.qbk
1 [/
2 (C) Copyright 2007-8 Anthony Williams.
3 (C) Copyright 2013 Oliver Kowalke.
4 Distributed under the Boost Software License, Version 1.0.
5 (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 ]
8
9 [section:barriers Barriers]
10
11 A barrier is a concept also known as a __rendezvous__, it is a synchronization
12 point between multiple contexts of execution (fibers). The barrier is
13 configured for a particular number of fibers (`n`), and as fibers reach the
14 barrier they must wait until all `n` fibers have arrived. Once the `n`-th
15 fiber has reached the barrier, all the waiting fibers can proceed, and the
16 barrier is reset.
17
18 The fact that the barrier automatically resets is significant. Consider a case
19 in which you launch some number of fibers and want to wait only until the
20 first of them has completed. You might be tempted to use a `barrier(2)` as the
21 synchronization mechanism, making each new fiber call its [member_link
22 barrier..wait] method, then calling `wait()` in the launching fiber to wait
23 until the first other fiber completes.
24
25 That will in fact unblock the launching fiber. The unfortunate part is that it
26 will continue blocking the ['remaining] fibers.
27
28 Consider the following scenario:
29
30 # Fiber ["main] launches fibers A, B, C and D, then calls `barrier::wait()`.
31 # Fiber C finishes first and likewise calls `barrier::wait()`.
32 # Fiber ["main] is unblocked, as desired.
33 # Fiber B calls `barrier::wait()`. Fiber B is ['blocked!]
34 # Fiber A calls `barrier::wait()`. Fibers A and B are unblocked.
35 # Fiber D calls `barrier::wait()`. Fiber D is blocked indefinitely.
36
37 (See also [link wait_first_simple_section when_any, simple completion].)
38
39 [note It is unwise to tie the lifespan of a barrier to any one of its
40 participating fibers. Although conceptually all waiting fibers awaken
41 ["simultaneously,] because of the nature of fibers, in practice they will
42 awaken one by one in indeterminate order.[footnote The current implementation
43 wakes fibers in FIFO order: the first to call `wait()` wakes first, and so
44 forth. But it is perilous to rely on the order in which the various fibers
45 will reach the `wait()` call.] The rest of the waiting fibers will
46 still be blocked in `wait()`, which must, before returning, access data
47 members in the barrier object.]
48
49 [class_heading barrier]
50
51 #include <boost/fiber/barrier.hpp>
52
53 namespace boost {
54 namespace fibers {
55
56 class barrier {
57 public:
58 explicit barrier( std::size_t);
59
60 barrier( barrier const&) = delete;
61 barrier & operator=( barrier const&) = delete;
62
63 bool wait();
64 };
65
66 }}
67
68
69 Instances of __barrier__ are not copyable or movable.
70
71 [heading Constructor]
72
73 explicit barrier( std::size_t initial);
74
75 [variablelist
76 [[Effects:] [Construct a barrier for `initial` fibers.]]
77 [[Throws:] [`fiber_error`]]
78 [[Error Conditions:] [
79 [*invalid_argument]: if `initial` is zero.]]
80 ]
81
82 [member_heading barrier..wait]
83
84 bool wait();
85
86 [variablelist
87 [[Effects:] [Block until `initial` fibers have called `wait` on `*this`. When
88 the `initial`-th fiber calls `wait`, all waiting fibers are unblocked, and
89 the barrier is reset. ]]
90 [[Returns:] [`true` for exactly one fiber from each batch of waiting fibers,
91 `false` otherwise.]]
92 [[Throws:] [__fiber_error__]]
93 ]
94
95 [endsect]