]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/thread/include/boost/thread/concurrent_queues/sync_deque.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / thread / include / boost / thread / concurrent_queues / sync_deque.hpp
1 #ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
2 #define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
3
4 //////////////////////////////////////////////////////////////////////////////
5 //
6 // (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
7 // Software License, Version 1.0. (See accompanying file
8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/thread for documentation.
11 //
12 //////////////////////////////////////////////////////////////////////////////
13
14 #include <boost/thread/detail/config.hpp>
15 #include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
16 #include <boost/thread/concurrent_queues/queue_op_status.hpp>
17 #include <boost/thread/condition_variable.hpp>
18 #include <boost/thread/csbl/devector.hpp>
19 #include <boost/thread/detail/move.hpp>
20 #include <boost/thread/mutex.hpp>
21
22 #include <boost/throw_exception.hpp>
23 #include <boost/smart_ptr/shared_ptr.hpp>
24 #include <boost/smart_ptr/make_shared.hpp>
25
26 #include <boost/config/abi_prefix.hpp>
27
28 namespace boost
29 {
30 namespace concurrent
31 {
32 template <class ValueType, class Container = csbl::devector<ValueType> >
33 class sync_deque
34 : public detail::sync_queue_base<ValueType, Container >
35 {
36 typedef detail::sync_queue_base<ValueType, Container > super;
37
38 public:
39 typedef ValueType value_type;
40 //typedef typename super::value_type value_type; // fixme
41 typedef typename super::underlying_queue_type underlying_queue_type;
42 typedef typename super::size_type size_type;
43 typedef typename super::op_status op_status;
44
45 // Constructors/Assignment/Destructors
46 BOOST_THREAD_NO_COPYABLE(sync_deque)
47 inline sync_deque();
48 //template <typename Range>
49 //inline explicit sync_deque(Range range);
50 inline ~sync_deque();
51
52 // Modifiers
53 inline void push_back(const value_type& x);
54 inline queue_op_status try_push_back(const value_type& x);
55 inline queue_op_status nonblocking_push_back(const value_type& x);
56 inline queue_op_status wait_push_back(const value_type& x);
57 inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
58 inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
59 inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
60 inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
61
62 // Observers/Modifiers
63 inline void pull_front(value_type&);
64 // enable_if is_nothrow_copy_movable<value_type>
65 inline value_type pull_front();
66
67 inline queue_op_status try_pull_front(value_type&);
68 inline queue_op_status nonblocking_pull_front(value_type&);
69 inline queue_op_status wait_pull_front(ValueType& elem);
70
71 private:
72
73 inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
74 inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
75 inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
76 inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
77 inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
78 inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
79
80 inline void pull_front(value_type& elem, unique_lock<mutex>& )
81 {
82 elem = boost::move(super::data_.front());
83 super::data_.pop_front();
84 }
85 inline value_type pull_front(unique_lock<mutex>& )
86 {
87 value_type e = boost::move(super::data_.front());
88 super::data_.pop_front();
89 return boost::move(e);
90 }
91
92 inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
93 {
94 super::data_.push_back(elem);
95 super::notify_not_empty_if_needed(lk);
96 }
97
98 inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
99 {
100 super::data_.push_back(boost::move(elem));
101 super::notify_not_empty_if_needed(lk);
102 }
103 };
104
105 template <class ValueType, class Container>
106 sync_deque<ValueType, Container>::sync_deque() :
107 super()
108 {
109 }
110
111 // template <class ValueType, class Container>
112 // template <class Range>
113 // explicit sync_deque<ValueType, Container>::sync_deque(Range range) :
114 // data_(), closed_(false)
115 // {
116 // try
117 // {
118 // typedef typename Range::iterator iterator_t;
119 // iterator_t first = boost::begin(range);
120 // iterator_t end = boost::end(range);
121 // for (iterator_t cur = first; cur != end; ++cur)
122 // {
123 // data_.push(boost::move(*cur));;
124 // }
125 // notify_not_empty_if_needed(lk);
126 // }
127 // catch (...)
128 // {
129 // delete[] data_;
130 // }
131 // }
132
133 template <class ValueType, class Container>
134 sync_deque<ValueType, Container>::~sync_deque()
135 {
136 }
137
138 template <class ValueType, class Container>
139 queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem, unique_lock<mutex>& lk)
140 {
141 if (super::empty(lk))
142 {
143 if (super::closed(lk)) return queue_op_status::closed;
144 return queue_op_status::empty;
145 }
146 pull_front(elem, lk);
147 return queue_op_status::success;
148 }
149 template <class ValueType, class Container>
150 queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
151 {
152 if (super::empty(lk))
153 {
154 if (super::closed(lk)) return queue_op_status::closed;
155 }
156 bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
157 if (has_been_closed) return queue_op_status::closed;
158 pull_front(elem, lk);
159 return queue_op_status::success;
160 }
161
162 template <class ValueType, class Container>
163 queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem)
164 {
165 unique_lock<mutex> lk(super::mtx_);
166 return try_pull_front(elem, lk);
167 }
168
169 template <class ValueType, class Container>
170 queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem)
171 {
172 unique_lock<mutex> lk(super::mtx_);
173 return wait_pull_front(elem, lk);
174 }
175
176 template <class ValueType, class Container>
177 queue_op_status sync_deque<ValueType, Container>::nonblocking_pull_front(ValueType& elem)
178 {
179 unique_lock<mutex> lk(super::mtx_, try_to_lock);
180 if (!lk.owns_lock())
181 {
182 return queue_op_status::busy;
183 }
184 return try_pull_front(elem, lk);
185 }
186
187 template <class ValueType, class Container>
188 void sync_deque<ValueType, Container>::pull_front(ValueType& elem)
189 {
190 unique_lock<mutex> lk(super::mtx_);
191 super::wait_until_not_empty(lk);
192 pull_front(elem, lk);
193 }
194
195 // enable if ValueType is nothrow movable
196 template <class ValueType, class Container>
197 ValueType sync_deque<ValueType, Container>::pull_front()
198 {
199 unique_lock<mutex> lk(super::mtx_);
200 super::wait_until_not_empty(lk);
201 return pull_front(lk);
202 }
203
204 template <class ValueType, class Container>
205 queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
206 {
207 if (super::closed(lk)) return queue_op_status::closed;
208 push_back(elem, lk);
209 return queue_op_status::success;
210 }
211
212 template <class ValueType, class Container>
213 queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem)
214 {
215 unique_lock<mutex> lk(super::mtx_);
216 return try_push_back(elem, lk);
217 }
218
219 template <class ValueType, class Container>
220 queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
221 {
222 if (super::closed(lk)) return queue_op_status::closed;
223 push_back(elem, lk);
224 return queue_op_status::success;
225 }
226
227 template <class ValueType, class Container>
228 queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem)
229 {
230 unique_lock<mutex> lk(super::mtx_);
231 return wait_push_back(elem, lk);
232 }
233
234 template <class ValueType, class Container>
235 queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(const ValueType& elem)
236 {
237 unique_lock<mutex> lk(super::mtx_, try_to_lock);
238 if (!lk.owns_lock()) return queue_op_status::busy;
239 return try_push_back(elem, lk);
240 }
241
242 template <class ValueType, class Container>
243 void sync_deque<ValueType, Container>::push_back(const ValueType& elem)
244 {
245 unique_lock<mutex> lk(super::mtx_);
246 super::throw_if_closed(lk);
247 push_back(elem, lk);
248 }
249
250 template <class ValueType, class Container>
251 queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
252 {
253 if (super::closed(lk)) return queue_op_status::closed;
254 push_back(boost::move(elem), lk);
255 return queue_op_status::success;
256 }
257
258 template <class ValueType, class Container>
259 queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
260 {
261 unique_lock<mutex> lk(super::mtx_);
262 return try_push_back(boost::move(elem), lk);
263 }
264
265 template <class ValueType, class Container>
266 queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
267 {
268 if (super::closed(lk)) return queue_op_status::closed;
269 push_back(boost::move(elem), lk);
270 return queue_op_status::success;
271 }
272
273 template <class ValueType, class Container>
274 queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
275 {
276 unique_lock<mutex> lk(super::mtx_);
277 return wait_push_back(boost::move(elem), lk);
278 }
279
280 template <class ValueType, class Container>
281 queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
282 {
283 unique_lock<mutex> lk(super::mtx_, try_to_lock);
284 if (!lk.owns_lock())
285 {
286 return queue_op_status::busy;
287 }
288 return try_push_back(boost::move(elem), lk);
289 }
290
291 template <class ValueType, class Container>
292 void sync_deque<ValueType, Container>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
293 {
294 unique_lock<mutex> lk(super::mtx_);
295 super::throw_if_closed(lk);
296 push_back(boost::move(elem), lk);
297 }
298
299 template <class ValueType, class Container>
300 sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
301 {
302 sbq.push_back(boost::move(elem));
303 return sbq;
304 }
305
306 template <class ValueType, class Container>
307 sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, ValueType const&elem)
308 {
309 sbq.push_back(elem);
310 return sbq;
311 }
312
313 template <class ValueType, class Container>
314 sync_deque<ValueType, Container>& operator>>(sync_deque<ValueType, Container>& sbq, ValueType &elem)
315 {
316 sbq.pull_front(elem);
317 return sbq;
318 }
319
320 }
321 using concurrent::sync_deque;
322
323 }
324
325 #include <boost/config/abi_suffix.hpp>
326
327 #endif