123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- // Copyright (c) 2022 Klemens D. Morgenstern
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_COBALT_WAIT_GROUP_HPP
- #define BOOST_COBALT_WAIT_GROUP_HPP
- #include <boost/cobalt/detail/wait_group.hpp>
- namespace boost::cobalt
- {
- // tag::outline[]
- struct wait_group
- {
- // create a wait_group
- explicit
- wait_group(asio::cancellation_type normal_cancel = asio::cancellation_type::none,
- asio::cancellation_type exception_cancel = asio::cancellation_type::all);
- // insert a task into the group
- void push_back(promise<void> p);
- // the number of tasks in the group
- std::size_t size() const;
- // remove completed tasks without waiting (i.e. zombie tasks)
- std::size_t reap();
- // cancel all tasks
- void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
- // end::outline[]
- /* tag::outline[]
- // wait for one task to complete.
- __wait_one_op__ wait_one();
- // wait for all tasks to complete
- __wait_op__ wait();
- // wait for all tasks to complete
- __wait_op__ operator co_await ();
- // when used with `with` , this will receive the exception
- // and wait for the completion
- // if `ep` is set, this will use the `exception_cancel` level,
- // otherwise the `normal_cancel` to cancel all promises.
- __wait_op__ await_exit(std::exception_ptr ep);
- end::outline[] */
- auto wait_one() -> detail::race_wrapper
- {
- return detail::race_wrapper(waitables_);
- }
- detail::gather_wrapper wait()
- {
- return detail::gather_wrapper(waitables_);
- }
- detail::gather_wrapper::awaitable_type operator co_await ()
- {
- return detail::gather_wrapper(waitables_).operator co_await();
- }
- // swallow the exception here.
- detail::gather_wrapper await_exit(std::exception_ptr ep)
- {
- auto ct = ep ? ct_except_ : ct_normal_;
- if (ct != asio::cancellation_type::none)
- for (auto & w : waitables_)
- w.cancel(ct);
- return detail::gather_wrapper(waitables_);
- }
- private:
- std::list<promise<void>> waitables_;
- asio::cancellation_type ct_normal_, ct_except_;
- // tag::outline[]
- };
- // end::outline[]
- inline wait_group::wait_group(
- asio::cancellation_type normal_cancel,
- asio::cancellation_type exception_cancel)
- : ct_normal_(normal_cancel), ct_except_(exception_cancel) {}
- inline
- std::size_t wait_group::size() const {return waitables_.size();}
- inline
- std::size_t wait_group::reap()
- {
- return erase_if(waitables_, [](promise<void> & p) { return p.ready() && p;});
- }
- inline
- void wait_group::cancel(asio::cancellation_type ct)
- {
- for (auto & w : waitables_)
- w.cancel(ct);
- }
- inline
- void wait_group::push_back(promise<void> p) { waitables_.push_back(std::move(p));}
- }
- #endif //BOOST_COBALT_WAIT_GROUP_HPP
|