105 lines
2.9 KiB
C++
105 lines
2.9 KiB
C++
// 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
|