Chris@16
|
1 #ifndef BOOST_THREAD_SYNC_QUEUE_HPP
|
Chris@16
|
2 #define BOOST_THREAD_SYNC_QUEUE_HPP
|
Chris@16
|
3
|
Chris@16
|
4 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
5 //
|
Chris@16
|
6 // (C) Copyright Vicente J. Botet Escriba 2013. Distributed under the Boost
|
Chris@16
|
7 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10 // See http://www.boost.org/libs/thread for documentation.
|
Chris@16
|
11 //
|
Chris@16
|
12 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/thread/detail/config.hpp>
|
Chris@16
|
15 #include <boost/thread/condition_variable.hpp>
|
Chris@16
|
16 #include <boost/thread/mutex.hpp>
|
Chris@16
|
17 #include <boost/thread/detail/move.hpp>
|
Chris@16
|
18 #include <boost/throw_exception.hpp>
|
Chris@16
|
19 #include <boost/smart_ptr/shared_ptr.hpp>
|
Chris@16
|
20 #include <boost/smart_ptr/make_shared.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/thread/sync_bounded_queue.hpp>
|
Chris@16
|
23 #include <boost/container/deque.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 #include <boost/config/abi_prefix.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 namespace boost
|
Chris@16
|
28 {
|
Chris@16
|
29
|
Chris@16
|
30
|
Chris@16
|
31 template <typename ValueType>
|
Chris@16
|
32 class sync_queue
|
Chris@16
|
33 {
|
Chris@16
|
34 public:
|
Chris@16
|
35 typedef ValueType value_type;
|
Chris@16
|
36 typedef std::size_t size_type;
|
Chris@16
|
37
|
Chris@16
|
38 // Constructors/Assignment/Destructors
|
Chris@16
|
39 BOOST_THREAD_NO_COPYABLE(sync_queue)
|
Chris@16
|
40 inline sync_queue();
|
Chris@16
|
41 //template <typename Range>
|
Chris@16
|
42 //inline explicit sync_queue(Range range);
|
Chris@16
|
43 inline ~sync_queue();
|
Chris@16
|
44
|
Chris@16
|
45 // Observers
|
Chris@16
|
46 inline bool empty() const;
|
Chris@16
|
47 inline bool full() const;
|
Chris@16
|
48 inline size_type size() const;
|
Chris@16
|
49 inline bool closed() const;
|
Chris@16
|
50
|
Chris@16
|
51 // Modifiers
|
Chris@16
|
52 inline void close();
|
Chris@16
|
53
|
Chris@16
|
54 inline void push(const value_type& x);
|
Chris@16
|
55 inline void push(BOOST_THREAD_RV_REF(value_type) x);
|
Chris@16
|
56 inline bool try_push(const value_type& x);
|
Chris@16
|
57 inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
|
Chris@16
|
58 inline bool try_push(no_block_tag, const value_type& x);
|
Chris@16
|
59 inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
|
Chris@16
|
60
|
Chris@16
|
61 // Observers/Modifiers
|
Chris@16
|
62 inline void pull(value_type&);
|
Chris@16
|
63 inline void pull(ValueType& elem, bool & closed);
|
Chris@16
|
64 // enable_if is_nothrow_copy_movable<value_type>
|
Chris@16
|
65 inline value_type pull();
|
Chris@16
|
66 inline shared_ptr<ValueType> ptr_pull();
|
Chris@16
|
67 inline bool try_pull(value_type&);
|
Chris@16
|
68 inline bool try_pull(no_block_tag,value_type&);
|
Chris@16
|
69 inline shared_ptr<ValueType> try_pull();
|
Chris@16
|
70
|
Chris@16
|
71 private:
|
Chris@16
|
72 mutable mutex mtx_;
|
Chris@16
|
73 condition_variable not_empty_;
|
Chris@16
|
74 size_type waiting_empty_;
|
Chris@16
|
75 boost::container::deque<ValueType> data_;
|
Chris@16
|
76 bool closed_;
|
Chris@16
|
77
|
Chris@16
|
78 inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
|
Chris@16
|
79 {
|
Chris@16
|
80 return data_.empty();
|
Chris@16
|
81 }
|
Chris@16
|
82 inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
|
Chris@16
|
83 {
|
Chris@16
|
84 return data_.empty();
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
|
Chris@16
|
88 {
|
Chris@16
|
89 return data_.size();
|
Chris@16
|
90 }
|
Chris@16
|
91
|
Chris@16
|
92 inline void throw_if_closed(unique_lock<mutex>&);
|
Chris@16
|
93
|
Chris@16
|
94 inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
|
Chris@16
|
95 inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
|
Chris@16
|
96 inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
Chris@16
|
97 inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
|
Chris@16
|
98
|
Chris@16
|
99 inline void wait_until_not_empty(unique_lock<mutex>& lk);
|
Chris@16
|
100 inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
|
Chris@16
|
101
|
Chris@16
|
102 inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
|
Chris@16
|
103 {
|
Chris@16
|
104 if (waiting_empty_ > 0)
|
Chris@16
|
105 {
|
Chris@16
|
106 --waiting_empty_;
|
Chris@16
|
107 lk.unlock();
|
Chris@16
|
108 not_empty_.notify_one();
|
Chris@16
|
109 }
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 inline void pull(value_type& elem, unique_lock<mutex>& )
|
Chris@16
|
113 {
|
Chris@16
|
114 elem = boost::move(data_.front());
|
Chris@16
|
115 data_.pop_front();
|
Chris@16
|
116 }
|
Chris@16
|
117 inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
|
Chris@16
|
118 {
|
Chris@16
|
119 shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_.front()));
|
Chris@16
|
120 data_.pop_front();
|
Chris@16
|
121 return res;
|
Chris@16
|
122 }
|
Chris@16
|
123
|
Chris@16
|
124 inline void push(const value_type& elem, unique_lock<mutex>& lk)
|
Chris@16
|
125 {
|
Chris@16
|
126 data_.push_back(elem);
|
Chris@16
|
127 notify_not_empty_if_needed(lk);
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
|
Chris@16
|
131 {
|
Chris@16
|
132 data_.push(boost::move(elem));
|
Chris@16
|
133 notify_not_empty_if_needed(lk);
|
Chris@16
|
134 }
|
Chris@16
|
135 };
|
Chris@16
|
136
|
Chris@16
|
137 template <typename ValueType>
|
Chris@16
|
138 sync_queue<ValueType>::sync_queue() :
|
Chris@16
|
139 waiting_empty_(0), data_(), closed_(false)
|
Chris@16
|
140 {
|
Chris@16
|
141 BOOST_ASSERT(data_.empty());
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 // template <typename ValueType>
|
Chris@16
|
145 // template <typename Range>
|
Chris@16
|
146 // explicit sync_queue<ValueType>::sync_queue(Range range) :
|
Chris@16
|
147 // waiting_empty_(0), data_(), closed_(false)
|
Chris@16
|
148 // {
|
Chris@16
|
149 // try
|
Chris@16
|
150 // {
|
Chris@16
|
151 // typedef typename Range::iterator iterator_t;
|
Chris@16
|
152 // iterator_t first = boost::begin(range);
|
Chris@16
|
153 // iterator_t end = boost::end(range);
|
Chris@16
|
154 // for (iterator_t cur = first; cur != end; ++cur)
|
Chris@16
|
155 // {
|
Chris@16
|
156 // data_.push(boost::move(*cur));;
|
Chris@16
|
157 // }
|
Chris@16
|
158 // notify_not_empty_if_needed(lk);
|
Chris@16
|
159 // }
|
Chris@16
|
160 // catch (...)
|
Chris@16
|
161 // {
|
Chris@16
|
162 // delete[] data_;
|
Chris@16
|
163 // }
|
Chris@16
|
164 // }
|
Chris@16
|
165
|
Chris@16
|
166 template <typename ValueType>
|
Chris@16
|
167 sync_queue<ValueType>::~sync_queue()
|
Chris@16
|
168 {
|
Chris@16
|
169 }
|
Chris@16
|
170
|
Chris@16
|
171 template <typename ValueType>
|
Chris@16
|
172 void sync_queue<ValueType>::close()
|
Chris@16
|
173 {
|
Chris@16
|
174 {
|
Chris@16
|
175 lock_guard<mutex> lk(mtx_);
|
Chris@16
|
176 closed_ = true;
|
Chris@16
|
177 }
|
Chris@16
|
178 not_empty_.notify_all();
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 template <typename ValueType>
|
Chris@16
|
182 bool sync_queue<ValueType>::closed() const
|
Chris@16
|
183 {
|
Chris@16
|
184 lock_guard<mutex> lk(mtx_);
|
Chris@16
|
185 return closed_;
|
Chris@16
|
186 }
|
Chris@16
|
187
|
Chris@16
|
188 template <typename ValueType>
|
Chris@16
|
189 bool sync_queue<ValueType>::empty() const
|
Chris@16
|
190 {
|
Chris@16
|
191 lock_guard<mutex> lk(mtx_);
|
Chris@16
|
192 return empty(lk);
|
Chris@16
|
193 }
|
Chris@16
|
194 template <typename ValueType>
|
Chris@16
|
195 bool sync_queue<ValueType>::full() const
|
Chris@16
|
196 {
|
Chris@16
|
197 return false;
|
Chris@16
|
198 }
|
Chris@16
|
199
|
Chris@16
|
200 template <typename ValueType>
|
Chris@16
|
201 typename sync_queue<ValueType>::size_type sync_queue<ValueType>::size() const
|
Chris@16
|
202 {
|
Chris@16
|
203 lock_guard<mutex> lk(mtx_);
|
Chris@16
|
204 return size(lk);
|
Chris@16
|
205 }
|
Chris@16
|
206
|
Chris@16
|
207
|
Chris@16
|
208 template <typename ValueType>
|
Chris@16
|
209 bool sync_queue<ValueType>::try_pull(ValueType& elem, unique_lock<mutex>& lk)
|
Chris@16
|
210 {
|
Chris@16
|
211 if (empty(lk))
|
Chris@16
|
212 {
|
Chris@16
|
213 throw_if_closed(lk);
|
Chris@16
|
214 return false;
|
Chris@16
|
215 }
|
Chris@16
|
216 pull(elem, lk);
|
Chris@16
|
217 return true;
|
Chris@16
|
218 }
|
Chris@16
|
219 template <typename ValueType>
|
Chris@16
|
220 shared_ptr<ValueType> sync_queue<ValueType>::try_pull(unique_lock<mutex>& lk)
|
Chris@16
|
221 {
|
Chris@16
|
222 if (empty(lk))
|
Chris@16
|
223 {
|
Chris@16
|
224 throw_if_closed(lk);
|
Chris@16
|
225 return shared_ptr<ValueType>();
|
Chris@16
|
226 }
|
Chris@16
|
227 return ptr_pull(lk);
|
Chris@16
|
228 }
|
Chris@16
|
229
|
Chris@16
|
230 template <typename ValueType>
|
Chris@16
|
231 bool sync_queue<ValueType>::try_pull(ValueType& elem)
|
Chris@16
|
232 {
|
Chris@16
|
233 try
|
Chris@16
|
234 {
|
Chris@16
|
235 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
236 return try_pull(elem, lk);
|
Chris@16
|
237 }
|
Chris@16
|
238 catch (...)
|
Chris@16
|
239 {
|
Chris@16
|
240 close();
|
Chris@16
|
241 throw;
|
Chris@16
|
242 }
|
Chris@16
|
243 }
|
Chris@16
|
244
|
Chris@16
|
245 template <typename ValueType>
|
Chris@16
|
246 bool sync_queue<ValueType>::try_pull(no_block_tag,ValueType& elem)
|
Chris@16
|
247 {
|
Chris@16
|
248 try
|
Chris@16
|
249 {
|
Chris@16
|
250 unique_lock<mutex> lk(mtx_, try_to_lock);
|
Chris@16
|
251 if (!lk.owns_lock())
|
Chris@16
|
252 {
|
Chris@16
|
253 return false;
|
Chris@16
|
254 }
|
Chris@16
|
255 return try_pull(elem, lk);
|
Chris@16
|
256 }
|
Chris@16
|
257 catch (...)
|
Chris@16
|
258 {
|
Chris@16
|
259 close();
|
Chris@16
|
260 throw;
|
Chris@16
|
261 }
|
Chris@16
|
262 }
|
Chris@16
|
263 template <typename ValueType>
|
Chris@16
|
264 boost::shared_ptr<ValueType> sync_queue<ValueType>::try_pull()
|
Chris@16
|
265 {
|
Chris@16
|
266 try
|
Chris@16
|
267 {
|
Chris@16
|
268 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
269 return try_pull(lk);
|
Chris@16
|
270 }
|
Chris@16
|
271 catch (...)
|
Chris@16
|
272 {
|
Chris@16
|
273 close();
|
Chris@16
|
274 throw;
|
Chris@16
|
275 }
|
Chris@16
|
276 }
|
Chris@16
|
277
|
Chris@16
|
278 template <typename ValueType>
|
Chris@16
|
279 void sync_queue<ValueType>::throw_if_closed(unique_lock<mutex>&)
|
Chris@16
|
280 {
|
Chris@16
|
281 if (closed_)
|
Chris@16
|
282 {
|
Chris@16
|
283 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
|
Chris@16
|
284 }
|
Chris@16
|
285 }
|
Chris@16
|
286
|
Chris@16
|
287 template <typename ValueType>
|
Chris@16
|
288 void sync_queue<ValueType>::wait_until_not_empty(unique_lock<mutex>& lk)
|
Chris@16
|
289 {
|
Chris@16
|
290 for (;;)
|
Chris@16
|
291 {
|
Chris@16
|
292 if (! empty(lk)) break;
|
Chris@16
|
293 throw_if_closed(lk);
|
Chris@16
|
294 ++waiting_empty_;
|
Chris@16
|
295 not_empty_.wait(lk);
|
Chris@16
|
296 }
|
Chris@16
|
297 }
|
Chris@16
|
298 template <typename ValueType>
|
Chris@16
|
299 void sync_queue<ValueType>::wait_until_not_empty(unique_lock<mutex>& lk, bool & closed)
|
Chris@16
|
300 {
|
Chris@16
|
301 for (;;)
|
Chris@16
|
302 {
|
Chris@16
|
303 if (! empty(lk)) break;
|
Chris@16
|
304 if (closed_) {closed=true; return;}
|
Chris@16
|
305 ++waiting_empty_;
|
Chris@16
|
306 not_empty_.wait(lk);
|
Chris@16
|
307 }
|
Chris@16
|
308 closed=false;
|
Chris@16
|
309 }
|
Chris@16
|
310
|
Chris@16
|
311 template <typename ValueType>
|
Chris@16
|
312 void sync_queue<ValueType>::pull(ValueType& elem)
|
Chris@16
|
313 {
|
Chris@16
|
314 try
|
Chris@16
|
315 {
|
Chris@16
|
316 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
317 wait_until_not_empty(lk);
|
Chris@16
|
318 pull(elem, lk);
|
Chris@16
|
319 }
|
Chris@16
|
320 catch (...)
|
Chris@16
|
321 {
|
Chris@16
|
322 close();
|
Chris@16
|
323 throw;
|
Chris@16
|
324 }
|
Chris@16
|
325 }
|
Chris@16
|
326 template <typename ValueType>
|
Chris@16
|
327 void sync_queue<ValueType>::pull(ValueType& elem, bool & closed)
|
Chris@16
|
328 {
|
Chris@16
|
329 try
|
Chris@16
|
330 {
|
Chris@16
|
331 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
332 wait_until_not_empty(lk, closed);
|
Chris@16
|
333 if (closed) {return;}
|
Chris@16
|
334 pull(elem, lk);
|
Chris@16
|
335 }
|
Chris@16
|
336 catch (...)
|
Chris@16
|
337 {
|
Chris@16
|
338 close();
|
Chris@16
|
339 throw;
|
Chris@16
|
340 }
|
Chris@16
|
341 }
|
Chris@16
|
342
|
Chris@16
|
343 // enable if ValueType is nothrow movable
|
Chris@16
|
344 template <typename ValueType>
|
Chris@16
|
345 ValueType sync_queue<ValueType>::pull()
|
Chris@16
|
346 {
|
Chris@16
|
347 try
|
Chris@16
|
348 {
|
Chris@16
|
349 value_type elem;
|
Chris@16
|
350 pull(elem);
|
Chris@16
|
351 return boost::move(elem);
|
Chris@16
|
352 }
|
Chris@16
|
353 catch (...)
|
Chris@16
|
354 {
|
Chris@16
|
355 close();
|
Chris@16
|
356 throw;
|
Chris@16
|
357 }
|
Chris@16
|
358 }
|
Chris@16
|
359 template <typename ValueType>
|
Chris@16
|
360 boost::shared_ptr<ValueType> sync_queue<ValueType>::ptr_pull()
|
Chris@16
|
361 {
|
Chris@16
|
362 try
|
Chris@16
|
363 {
|
Chris@16
|
364 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
365 wait_until_not_empty(lk);
|
Chris@16
|
366 return ptr_pull(lk);
|
Chris@16
|
367 }
|
Chris@16
|
368 catch (...)
|
Chris@16
|
369 {
|
Chris@16
|
370 close();
|
Chris@16
|
371 throw;
|
Chris@16
|
372 }
|
Chris@16
|
373 }
|
Chris@16
|
374
|
Chris@16
|
375 template <typename ValueType>
|
Chris@16
|
376 bool sync_queue<ValueType>::try_push(const ValueType& elem, unique_lock<mutex>& lk)
|
Chris@16
|
377 {
|
Chris@16
|
378 throw_if_closed(lk);
|
Chris@16
|
379 push(elem, lk);
|
Chris@16
|
380 return true;
|
Chris@16
|
381 }
|
Chris@16
|
382
|
Chris@16
|
383 template <typename ValueType>
|
Chris@16
|
384 bool sync_queue<ValueType>::try_push(const ValueType& elem)
|
Chris@16
|
385 {
|
Chris@16
|
386 try
|
Chris@16
|
387 {
|
Chris@16
|
388 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
389 return try_push(elem, lk);
|
Chris@16
|
390 }
|
Chris@16
|
391 catch (...)
|
Chris@16
|
392 {
|
Chris@16
|
393 close();
|
Chris@16
|
394 throw;
|
Chris@16
|
395 }
|
Chris@16
|
396 }
|
Chris@16
|
397
|
Chris@16
|
398 template <typename ValueType>
|
Chris@16
|
399 bool sync_queue<ValueType>::try_push(no_block_tag, const ValueType& elem)
|
Chris@16
|
400 {
|
Chris@16
|
401 try
|
Chris@16
|
402 {
|
Chris@16
|
403 unique_lock<mutex> lk(mtx_, try_to_lock);
|
Chris@16
|
404 if (!lk.owns_lock()) return false;
|
Chris@16
|
405 return try_push(elem, lk);
|
Chris@16
|
406 }
|
Chris@16
|
407 catch (...)
|
Chris@16
|
408 {
|
Chris@16
|
409 close();
|
Chris@16
|
410 throw;
|
Chris@16
|
411 }
|
Chris@16
|
412 }
|
Chris@16
|
413
|
Chris@16
|
414 template <typename ValueType>
|
Chris@16
|
415 void sync_queue<ValueType>::push(const ValueType& elem)
|
Chris@16
|
416 {
|
Chris@16
|
417 try
|
Chris@16
|
418 {
|
Chris@16
|
419 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
420 throw_if_closed(lk);
|
Chris@16
|
421 push(elem, lk);
|
Chris@16
|
422 }
|
Chris@16
|
423 catch (...)
|
Chris@16
|
424 {
|
Chris@16
|
425 close();
|
Chris@16
|
426 throw;
|
Chris@16
|
427 }
|
Chris@16
|
428 }
|
Chris@16
|
429
|
Chris@16
|
430 template <typename ValueType>
|
Chris@16
|
431 bool sync_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
Chris@16
|
432 {
|
Chris@16
|
433 throw_if_closed(lk);
|
Chris@16
|
434 push(boost::forward<ValueType>(elem), lk);
|
Chris@16
|
435 return true;
|
Chris@16
|
436 }
|
Chris@16
|
437
|
Chris@16
|
438 template <typename ValueType>
|
Chris@16
|
439 bool sync_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem)
|
Chris@16
|
440 {
|
Chris@16
|
441 try
|
Chris@16
|
442 {
|
Chris@16
|
443 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
444 return try_push(elem, lk);
|
Chris@16
|
445 }
|
Chris@16
|
446 catch (...)
|
Chris@16
|
447 {
|
Chris@16
|
448 close();
|
Chris@16
|
449 throw;
|
Chris@16
|
450 }
|
Chris@16
|
451 }
|
Chris@16
|
452
|
Chris@16
|
453 template <typename ValueType>
|
Chris@16
|
454 bool sync_queue<ValueType>::try_push(no_block_tag, BOOST_THREAD_RV_REF(ValueType) elem)
|
Chris@16
|
455 {
|
Chris@16
|
456 try
|
Chris@16
|
457 {
|
Chris@16
|
458 unique_lock<mutex> lk(mtx_, try_to_lock);
|
Chris@16
|
459 if (!lk.owns_lock())
|
Chris@16
|
460 {
|
Chris@16
|
461 return false;
|
Chris@16
|
462 }
|
Chris@16
|
463 return try_push(elem, lk);
|
Chris@16
|
464 }
|
Chris@16
|
465 catch (...)
|
Chris@16
|
466 {
|
Chris@16
|
467 close();
|
Chris@16
|
468 throw;
|
Chris@16
|
469 }
|
Chris@16
|
470 }
|
Chris@16
|
471
|
Chris@16
|
472 template <typename ValueType>
|
Chris@16
|
473 void sync_queue<ValueType>::push(BOOST_THREAD_RV_REF(ValueType) elem)
|
Chris@16
|
474 {
|
Chris@16
|
475 try
|
Chris@16
|
476 {
|
Chris@16
|
477 unique_lock<mutex> lk(mtx_);
|
Chris@16
|
478 throw_if_closed(lk);
|
Chris@16
|
479 push(elem, lk);
|
Chris@16
|
480 }
|
Chris@16
|
481 catch (...)
|
Chris@16
|
482 {
|
Chris@16
|
483 close();
|
Chris@16
|
484 throw;
|
Chris@16
|
485 }
|
Chris@16
|
486 }
|
Chris@16
|
487
|
Chris@16
|
488 template <typename ValueType>
|
Chris@16
|
489 sync_queue<ValueType>& operator<<(sync_queue<ValueType>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
|
Chris@16
|
490 {
|
Chris@16
|
491 sbq.push(boost::forward<ValueType>(elem));
|
Chris@16
|
492 return sbq;
|
Chris@16
|
493 }
|
Chris@16
|
494
|
Chris@16
|
495 template <typename ValueType>
|
Chris@16
|
496 sync_queue<ValueType>& operator<<(sync_queue<ValueType>& sbq, ValueType const&elem)
|
Chris@16
|
497 {
|
Chris@16
|
498 sbq.push(elem);
|
Chris@16
|
499 return sbq;
|
Chris@16
|
500 }
|
Chris@16
|
501
|
Chris@16
|
502 template <typename ValueType>
|
Chris@16
|
503 sync_queue<ValueType>& operator>>(sync_queue<ValueType>& sbq, ValueType &elem)
|
Chris@16
|
504 {
|
Chris@16
|
505 sbq.pull(elem);
|
Chris@16
|
506 return sbq;
|
Chris@16
|
507 }
|
Chris@16
|
508
|
Chris@16
|
509 }
|
Chris@16
|
510
|
Chris@16
|
511 #include <boost/config/abi_suffix.hpp>
|
Chris@16
|
512
|
Chris@16
|
513 #endif
|