Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:30

0001 // Distributed under the Boost Software License, Version 1.0. (See
0002 // accompanying file LICENSE_1_0.txt or copy at
0003 // http://www.boost.org/LICENSE_1_0.txt)
0004 // (C) Copyright 2013 Vicente J. Botet Escriba
0005 
0006 #ifndef BOOST_THREAD_LATCH_HPP
0007 #define BOOST_THREAD_LATCH_HPP
0008 
0009 #include <boost/thread/detail/config.hpp>
0010 #include <boost/thread/detail/delete.hpp>
0011 #include <boost/thread/detail/counter.hpp>
0012 
0013 #include <boost/thread/mutex.hpp>
0014 #include <boost/thread/lock_types.hpp>
0015 #include <boost/thread/condition_variable.hpp>
0016 #include <boost/chrono/duration.hpp>
0017 #include <boost/chrono/time_point.hpp>
0018 #include <boost/assert.hpp>
0019 
0020 #include <boost/config/abi_prefix.hpp>
0021 
0022 namespace boost
0023 {
0024   class latch
0025   {
0026     /// @Requires: count_ must be greater than 0
0027     /// Effect: Decrement the count. Unlocks the lock and notify anyone waiting if we reached zero.
0028     /// Returns: true if count_ reached the value 0.
0029     /// @ThreadSafe ensured by the @c lk parameter
0030     bool count_down(unique_lock<mutex> &)
0031     /// pre_condition (count_ > 0)
0032     {
0033       BOOST_ASSERT(count_ > 0);
0034       if (--count_ == 0)
0035       {
0036         ++generation_;
0037         //lk.unlock();
0038         cond_.notify_all();
0039         return true;
0040       }
0041       return false;
0042     }
0043     /// Effect: Decrement the count is > 0. Unlocks the lock notify anyone waiting if we reached zero.
0044     /// Returns: true if count_ is 0.
0045     /// @ThreadSafe ensured by the @c lk parameter
0046     bool try_count_down(unique_lock<mutex> &lk)
0047     {
0048       if (count_ > 0)
0049       {
0050         return count_down(lk);
0051       }
0052       return true;
0053     }
0054   public:
0055     BOOST_THREAD_NO_COPYABLE( latch)
0056 
0057     /// Constructs a latch with a given count.
0058     latch(std::size_t count) :
0059       count_(count), generation_(0)
0060     {
0061     }
0062 
0063     /// Destructor
0064     /// Precondition: No threads are waiting or invoking count_down on @c *this.
0065 
0066     ~latch()
0067     {
0068 
0069     }
0070 
0071     /// Blocks until the latch has counted down to zero.
0072     void wait()
0073     {
0074       boost::unique_lock<boost::mutex> lk(mutex_);
0075       if (count_ == 0) return;
0076       std::size_t generation(generation_);
0077       cond_.wait(lk, detail::not_equal(generation, generation_));
0078     }
0079 
0080     /// @return true if the internal counter is already 0, false otherwise
0081     bool try_wait()
0082     {
0083       boost::unique_lock<boost::mutex> lk(mutex_);
0084       return (count_ == 0);
0085     }
0086 
0087     /// try to wait for a specified amount of time is elapsed.
0088     /// @return whether there is a timeout or not.
0089     template <class Rep, class Period>
0090     cv_status wait_for(const chrono::duration<Rep, Period>& rel_time)
0091     {
0092       boost::unique_lock<boost::mutex> lk(mutex_);
0093       if (count_ == 0) return cv_status::no_timeout;
0094       std::size_t generation(generation_);
0095       return cond_.wait_for(lk, rel_time, detail::not_equal(generation, generation_))
0096               ? cv_status::no_timeout
0097               : cv_status::timeout;
0098     }
0099 
0100     /// try to wait until the specified time_point is reached
0101     /// @return whether there were a timeout or not.
0102     template <class Clock, class Duration>
0103     cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time)
0104     {
0105       boost::unique_lock<boost::mutex> lk(mutex_);
0106       if (count_ == 0) return cv_status::no_timeout;
0107       std::size_t generation(generation_);
0108       return cond_.wait_until(lk, abs_time, detail::not_equal(generation, generation_))
0109           ? cv_status::no_timeout
0110           : cv_status::timeout;
0111     }
0112 
0113     /// Decrement the count and notify anyone waiting if we reach zero.
0114     /// @Requires count must be greater than 0
0115     void count_down()
0116     {
0117       boost::unique_lock<boost::mutex> lk(mutex_);
0118       count_down(lk);
0119     }
0120     /// Effect: Decrement the count if it is > 0 and notify anyone waiting if we reached zero.
0121     /// Returns: true if count_ was 0 or reached 0.
0122     bool try_count_down()
0123     {
0124       boost::unique_lock<boost::mutex> lk(mutex_);
0125       return try_count_down(lk);
0126     }
0127     void signal()
0128     {
0129       count_down();
0130     }
0131 
0132     /// Decrement the count and notify anyone waiting if we reach zero.
0133     /// Blocks until the latch has counted down to zero.
0134     /// @Requires count must be greater than 0
0135     void count_down_and_wait()
0136     {
0137       boost::unique_lock<boost::mutex> lk(mutex_);
0138       std::size_t generation(generation_);
0139       if (count_down(lk))
0140       {
0141         return;
0142       }
0143       cond_.wait(lk, detail::not_equal(generation, generation_));
0144     }
0145     void sync()
0146     {
0147       count_down_and_wait();
0148     }
0149 
0150     /// Reset the counter
0151     /// #Requires This method may only be invoked when there are no other threads currently inside the count_down_and_wait() method.
0152     void reset(std::size_t count)
0153     {
0154       boost::lock_guard<boost::mutex> lk(mutex_);
0155       //BOOST_ASSERT(count_ == 0);
0156       count_ = count;
0157     }
0158 
0159   private:
0160     mutex mutex_;
0161     condition_variable cond_;
0162     std::size_t count_;
0163     std::size_t generation_;
0164   };
0165 
0166 } // namespace boost
0167 
0168 #include <boost/config/abi_suffix.hpp>
0169 
0170 #endif