1// Copyright (c) 2022 Klemens D. Morgenstern
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5#ifndef BOOST_COBALT_WAIT_GROUP_HPP
6#define BOOST_COBALT_WAIT_GROUP_HPP
7
8#include <boost/cobalt/detail/wait_group.hpp>
9
10namespace boost::cobalt
11{
12// tag::outline[]
13struct wait_group
14{
15 // create a wait_group
16 explicit
17 wait_group(asio::cancellation_type normal_cancel = asio::cancellation_type::none,
18 asio::cancellation_type exception_cancel = asio::cancellation_type::all);
19
20 // insert a task into the group
21 void push_back(promise<void> p);
22
23 // the number of tasks in the group
24 std::size_t size() const;
25 // remove completed tasks without waiting (i.e. zombie tasks)
26 std::size_t reap();
27 // cancel all tasks
28 void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
29 // end::outline[]
30
31 /* tag::outline[]
32 // wait for one task to complete.
33 __wait_one_op__ wait_one();
34 // wait for all tasks to complete
35 __wait_op__ wait();
36 // wait for all tasks to complete
37 __wait_op__ operator co_await ();
38 // when used with `with` , this will receive the exception
39 // and wait for the completion
40 // if `ep` is set, this will use the `exception_cancel` level,
41 // otherwise the `normal_cancel` to cancel all promises.
42 __wait_op__ await_exit(std::exception_ptr ep);
43 end::outline[] */
44
45 auto wait_one() -> detail::race_wrapper
46 {
47 return detail::race_wrapper(waitables_);
48 }
49
50 detail::gather_wrapper wait()
51 {
52 return detail::gather_wrapper(waitables_);
53
54 }
55 detail::gather_wrapper::awaitable_type operator co_await ()
56 {
57 return detail::gather_wrapper(waitables_).operator co_await();
58 }
59 // swallow the exception here.
60 detail::gather_wrapper await_exit(std::exception_ptr ep)
61 {
62 auto ct = ep ? ct_except_ : ct_normal_;
63 if (ct != asio::cancellation_type::none)
64 for (auto & w : waitables_)
65 w.cancel(ct);
66 return detail::gather_wrapper(waitables_);
67 }
68
69
70 private:
71 std::list<promise<void>> waitables_;
72 asio::cancellation_type ct_normal_, ct_except_;
73 // tag::outline[]
74};
75// end::outline[]
76
77inline wait_group::wait_group(
78 asio::cancellation_type normal_cancel,
79 asio::cancellation_type exception_cancel)
80: ct_normal_(normal_cancel), ct_except_(exception_cancel) {}
81
82inline
83std::size_t wait_group::size() const {return waitables_.size();}
84
85inline
86std::size_t wait_group::reap()
87{
88 return erase_if(cont&: waitables_, pred: [](promise<void> & p) { return p.ready() && p;});
89}
90
91inline
92void wait_group::cancel(asio::cancellation_type ct)
93{
94 for (auto & w : waitables_)
95 w.cancel(ct);
96}
97
98inline
99void wait_group::push_back(promise<void> p) { waitables_.push_back(x: std::move(p));}
100
101
102}
103
104#endif //BOOST_COBALT_WAIT_GROUP_HPP
105

source code of boost/libs/cobalt/include/boost/cobalt/wait_group.hpp