Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:51

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // Copyright (c) Lewis Baker
0003 // Licenced under MIT license. See LICENSE.txt for details.
0004 ///////////////////////////////////////////////////////////////////////////////
0005 #ifndef CPPCORO_ASYNC_LATCH_HPP_INCLUDED
0006 #define CPPCORO_ASYNC_LATCH_HPP_INCLUDED
0007 
0008 #include <cppcoro/async_manual_reset_event.hpp>
0009 
0010 #include <atomic>
0011 #include <cstdint>
0012 
0013 namespace cppcoro
0014 {
0015     class async_latch
0016     {
0017     public:
0018 
0019         /// Construct the latch with the specified initial count.
0020         ///
0021         /// \param initialCount
0022         /// The initial count of the latch. The latch will become signalled once
0023         /// \c this->count_down() has been called \p initialCount times.
0024         /// The latch will be immediately signalled on construction if this
0025         /// parameter is zero or negative.
0026         async_latch(std::ptrdiff_t initialCount) noexcept
0027             : m_count(initialCount)
0028             , m_event(initialCount <= 0)
0029         {}
0030 
0031         /// Query if the latch has become signalled.
0032         ///
0033         /// The latch is marked as signalled once the count reaches zero.
0034         bool is_ready() const noexcept { return m_event.is_set(); }
0035 
0036         /// Decrement the count by n.
0037         ///
0038         /// Any coroutines awaiting this latch will be resumed once the count
0039         /// reaches zero. ie. when this method has been called at least 'initialCount'
0040         /// times.
0041         ///
0042         /// Any awaiting coroutines that are currently suspended waiting for the
0043         /// latch to become signalled will be resumed inside the last call to this
0044         /// method (ie. the call that decrements the count to zero).
0045         ///
0046         /// \param n
0047         /// The amount to decrement the count by.
0048         void count_down(std::ptrdiff_t n = 1) noexcept
0049         {
0050             if (m_count.fetch_sub(n, std::memory_order_acq_rel) <= n)
0051             {
0052                 m_event.set();
0053             }
0054         }
0055 
0056         /// Allows the latch to be awaited within a coroutine.
0057         ///
0058         /// If the latch is already signalled (ie. the count has been decremented
0059         /// to zero) then the awaiting coroutine will continue without suspending.
0060         /// Otherwise, the coroutine will suspend and will later be resumed inside
0061         /// a call to `count_down()`.
0062         auto operator co_await() const noexcept
0063         {
0064             return m_event.operator co_await();
0065         }
0066 
0067     private:
0068 
0069         std::atomic<std::ptrdiff_t> m_count;
0070         async_manual_reset_event m_event;
0071 
0072     };
0073 }
0074 
0075 #endif