Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:27

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_COBALT_WAIT_GROUP_HPP
0006 #define BOOST_COBALT_WAIT_GROUP_HPP
0007 
0008 #include <boost/cobalt/detail/wait_group.hpp>
0009 
0010 namespace boost::cobalt
0011 {
0012 // tag::outline[]
0013 struct wait_group
0014 {
0015     // create a wait_group
0016     explicit
0017     wait_group(asio::cancellation_type normal_cancel = asio::cancellation_type::none,
0018                asio::cancellation_type exception_cancel = asio::cancellation_type::all);
0019 
0020     // insert a task into the group
0021     void push_back(promise<void> p);
0022 
0023     // the number of tasks in the group
0024     std::size_t size() const;
0025     // remove completed tasks without waiting (i.e. zombie tasks)
0026     std::size_t reap();
0027     // cancel all tasks
0028     void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
0029     // end::outline[]
0030 
0031     /* tag::outline[]
0032     // wait for one task to complete.
0033     __wait_one_op__ wait_one();
0034     // wait for all tasks to complete
0035     __wait_op__ wait();
0036     // wait for all tasks to complete
0037     __wait_op__ operator co_await ();
0038     // when used with `with` , this will receive the exception
0039     // and wait for the completion
0040     // if `ep` is set, this will use the `exception_cancel` level,
0041     // otherwise the `normal_cancel` to cancel all promises.
0042     __wait_op__ await_exit(std::exception_ptr ep);
0043      end::outline[] */
0044 
0045     auto wait_one() -> detail::race_wrapper
0046     {
0047         return  detail::race_wrapper(waitables_);
0048     }
0049 
0050     detail::gather_wrapper wait()
0051     {
0052         return detail::gather_wrapper(waitables_);
0053 
0054     }
0055     detail::gather_wrapper::awaitable_type operator co_await ()
0056     {
0057       return detail::gather_wrapper(waitables_).operator co_await();
0058     }
0059     // swallow the exception here.
0060     detail::gather_wrapper await_exit(std::exception_ptr ep)
0061     {
0062         auto ct = ep ? ct_except_ : ct_normal_;
0063         if (ct != asio::cancellation_type::none)
0064             for (auto & w : waitables_)
0065                 w.cancel(ct);
0066         return detail::gather_wrapper(waitables_);
0067     }
0068 
0069 
0070   private:
0071     std::list<promise<void>> waitables_;
0072     asio::cancellation_type ct_normal_, ct_except_;
0073   // tag::outline[]
0074 };
0075 // end::outline[]
0076 
0077 inline wait_group::wait_group(
0078     asio::cancellation_type normal_cancel,
0079     asio::cancellation_type exception_cancel)
0080 : ct_normal_(normal_cancel), ct_except_(exception_cancel) {}
0081 
0082 inline
0083 std::size_t wait_group::size() const {return waitables_.size();}
0084 
0085 inline
0086 std::size_t wait_group::reap()
0087 {
0088   return erase_if(waitables_, [](promise<void> & p) { return p.ready() && p;});
0089 }
0090 
0091 inline
0092 void wait_group::cancel(asio::cancellation_type ct)
0093 {
0094   for (auto & w : waitables_)
0095     w.cancel(ct);
0096 }
0097 
0098 inline
0099 void wait_group::push_back(promise<void> p) { waitables_.push_back(std::move(p));}
0100 
0101 
0102 }
0103 
0104 #endif //BOOST_COBALT_WAIT_GROUP_HPP