File indexing completed on 2025-12-15 10:09:30
0001
0002
0003
0004
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
0027
0028
0029
0030 bool count_down(unique_lock<mutex> &)
0031
0032 {
0033 BOOST_ASSERT(count_ > 0);
0034 if (--count_ == 0)
0035 {
0036 ++generation_;
0037
0038 cond_.notify_all();
0039 return true;
0040 }
0041 return false;
0042 }
0043
0044
0045
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
0058 latch(std::size_t count) :
0059 count_(count), generation_(0)
0060 {
0061 }
0062
0063
0064
0065
0066 ~latch()
0067 {
0068
0069 }
0070
0071
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
0081 bool try_wait()
0082 {
0083 boost::unique_lock<boost::mutex> lk(mutex_);
0084 return (count_ == 0);
0085 }
0086
0087
0088
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
0101
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
0114
0115 void count_down()
0116 {
0117 boost::unique_lock<boost::mutex> lk(mutex_);
0118 count_down(lk);
0119 }
0120
0121
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
0133
0134
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
0151
0152 void reset(std::size_t count)
0153 {
0154 boost::lock_guard<boost::mutex> lk(mutex_);
0155
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 }
0167
0168 #include <boost/config/abi_suffix.hpp>
0169
0170 #endif