Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/thread/latch.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Distributed under the Boost Software License, Version 1.0. (See | |
2 // accompanying file LICENSE_1_0.txt or copy at | |
3 // http://www.boost.org/LICENSE_1_0.txt) | |
4 // (C) Copyright 2013 Vicente J. Botet Escriba | |
5 | |
6 #ifndef BOOST_THREAD_LATCH_HPP | |
7 #define BOOST_THREAD_LATCH_HPP | |
8 | |
9 #include <boost/thread/detail/config.hpp> | |
10 #include <boost/thread/detail/delete.hpp> | |
11 #include <boost/thread/detail/counter.hpp> | |
12 | |
13 #include <boost/thread/mutex.hpp> | |
14 #include <boost/thread/lock_types.hpp> | |
15 #include <boost/thread/condition_variable.hpp> | |
16 #include <boost/chrono/duration.hpp> | |
17 #include <boost/chrono/time_point.hpp> | |
18 #include <boost/assert.hpp> | |
19 | |
20 #include <boost/config/abi_prefix.hpp> | |
21 | |
22 namespace boost | |
23 { | |
24 class latch | |
25 { | |
26 /// @Requires: count_ must be greater than 0 | |
27 /// Effect: Decrement the count. Unlocks the lock and notify anyone waiting if we reached zero. | |
28 /// Returns: true if count_ reached the value 0. | |
29 /// @ThreadSafe ensured by the @c lk parameter | |
30 bool count_down(unique_lock<mutex> &lk) | |
31 /// pre_condition (count_ > 0) | |
32 { | |
33 BOOST_ASSERT(count_ > 0); | |
34 if (--count_ == 0) | |
35 { | |
36 ++generation_; | |
37 lk.unlock(); | |
38 cond_.notify_all(); | |
39 return true; | |
40 } | |
41 return false; | |
42 } | |
43 /// Effect: Decrement the count is > 0. Unlocks the lock notify anyone waiting if we reached zero. | |
44 /// Returns: true if count_ is 0. | |
45 /// @ThreadSafe ensured by the @c lk parameter | |
46 bool try_count_down(unique_lock<mutex> &lk) | |
47 { | |
48 if (count_ > 0) | |
49 { | |
50 return count_down(lk); | |
51 } | |
52 return true; | |
53 } | |
54 public: | |
55 BOOST_THREAD_NO_COPYABLE( latch) | |
56 | |
57 /// Constructs a latch with a given count. | |
58 latch(std::size_t count) : | |
59 count_(count), generation_(0) | |
60 { | |
61 } | |
62 | |
63 /// Destructor | |
64 /// Precondition: No threads are waiting or invoking count_down on @c *this. | |
65 | |
66 ~latch() | |
67 { | |
68 | |
69 } | |
70 | |
71 /// Blocks until the latch has counted down to zero. | |
72 void wait() | |
73 { | |
74 boost::unique_lock<boost::mutex> lk(mutex_); | |
75 std::size_t generation(generation_); | |
76 cond_.wait(lk, detail::not_equal(generation, generation_)); | |
77 } | |
78 | |
79 /// @return true if the internal counter is already 0, false otherwise | |
80 bool try_wait() | |
81 { | |
82 boost::unique_lock<boost::mutex> lk(mutex_); | |
83 return (count_ == 0); | |
84 } | |
85 | |
86 /// try to wait for a specified amount of time is elapsed. | |
87 /// @return whether there is a timeout or not. | |
88 template <class Rep, class Period> | |
89 cv_status wait_for(const chrono::duration<Rep, Period>& rel_time) | |
90 { | |
91 boost::unique_lock<boost::mutex> lk(mutex_); | |
92 std::size_t generation(generation_); | |
93 return cond_.wait_for(lk, rel_time, detail::not_equal(generation, generation_)) | |
94 ? cv_status::no_timeout | |
95 : cv_status::timeout; | |
96 } | |
97 | |
98 /// try to wait until the specified time_point is reached | |
99 /// @return whether there were a timeout or not. | |
100 template <class Clock, class Duration> | |
101 cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) | |
102 { | |
103 boost::unique_lock<boost::mutex> lk(mutex_); | |
104 std::size_t generation(generation_); | |
105 return cond_.wait_until(lk, abs_time, detail::not_equal(generation, generation_)) | |
106 ? cv_status::no_timeout | |
107 : cv_status::timeout; | |
108 } | |
109 | |
110 /// Decrement the count and notify anyone waiting if we reach zero. | |
111 /// @Requires count must be greater than 0 | |
112 void count_down() | |
113 { | |
114 boost::unique_lock<boost::mutex> lk(mutex_); | |
115 count_down(lk); | |
116 } | |
117 /// Effect: Decrement the count if it is > 0 and notify anyone waiting if we reached zero. | |
118 /// Returns: true if count_ was 0 or reached 0. | |
119 bool try_count_down() | |
120 { | |
121 boost::unique_lock<boost::mutex> lk(mutex_); | |
122 return try_count_down(lk); | |
123 } | |
124 void signal() | |
125 { | |
126 count_down(); | |
127 } | |
128 | |
129 /// Decrement the count and notify anyone waiting if we reach zero. | |
130 /// Blocks until the latch has counted down to zero. | |
131 /// @Requires count must be greater than 0 | |
132 void count_down_and_wait() | |
133 { | |
134 boost::unique_lock<boost::mutex> lk(mutex_); | |
135 std::size_t generation(generation_); | |
136 if (count_down(lk)) | |
137 { | |
138 return; | |
139 } | |
140 cond_.wait(lk, detail::not_equal(generation, generation_)); | |
141 } | |
142 void sync() | |
143 { | |
144 count_down_and_wait(); | |
145 } | |
146 | |
147 /// Reset the counter | |
148 /// #Requires This method may only be invoked when there are no other threads currently inside the count_down_and_wait() method. | |
149 void reset(std::size_t count) | |
150 { | |
151 boost::lock_guard<boost::mutex> lk(mutex_); | |
152 //BOOST_ASSERT(count_ == 0); | |
153 count_ = count; | |
154 } | |
155 | |
156 private: | |
157 mutex mutex_; | |
158 condition_variable cond_; | |
159 std::size_t count_; | |
160 std::size_t generation_; | |
161 }; | |
162 | |
163 } // namespace boost | |
164 | |
165 #include <boost/config/abi_suffix.hpp> | |
166 | |
167 #endif |