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 2007 Anthony Williams |
5 | // (C) Copyright 2011-2012 Vicente J. Botet Escriba |
6 | |
7 | #ifndef BOOST_THREAD_LOCK_TYPES_HPP |
8 | #define BOOST_THREAD_LOCK_TYPES_HPP |
9 | |
10 | #include <boost/thread/detail/config.hpp> |
11 | #include <boost/thread/detail/move.hpp> |
12 | #include <boost/thread/exceptions.hpp> |
13 | #include <boost/thread/lock_options.hpp> |
14 | #include <boost/thread/lockable_traits.hpp> |
15 | #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS |
16 | #include <boost/thread/is_locked_by_this_thread.hpp> |
17 | #endif |
18 | #include <boost/thread/thread_time.hpp> |
19 | |
20 | #include <boost/assert.hpp> |
21 | #ifdef BOOST_THREAD_USES_CHRONO |
22 | #include <boost/chrono/time_point.hpp> |
23 | #include <boost/chrono/duration.hpp> |
24 | #endif |
25 | #include <boost/detail/workaround.hpp> |
26 | |
27 | #include <boost/config/abi_prefix.hpp> |
28 | |
29 | namespace boost |
30 | { |
31 | struct xtime; |
32 | |
33 | template <typename Mutex> |
34 | class shared_lock; |
35 | |
36 | template <typename Mutex> |
37 | class upgrade_lock; |
38 | |
39 | template <typename Mutex> |
40 | class unique_lock; |
41 | |
42 | namespace detail |
43 | { |
44 | template <typename Mutex> |
45 | class try_lock_wrapper; |
46 | } |
47 | |
48 | #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES |
49 | namespace sync |
50 | { |
51 | template<typename T> |
52 | struct is_basic_lockable<unique_lock<T> > |
53 | { |
54 | BOOST_STATIC_CONSTANT(bool, value = true); |
55 | }; |
56 | template<typename T> |
57 | struct is_lockable<unique_lock<T> > |
58 | { |
59 | BOOST_STATIC_CONSTANT(bool, value = true); |
60 | }; |
61 | |
62 | template<typename T> |
63 | struct is_basic_lockable<shared_lock<T> > |
64 | { |
65 | BOOST_STATIC_CONSTANT(bool, value = true); |
66 | }; |
67 | template<typename T> |
68 | struct is_lockable<shared_lock<T> > |
69 | { |
70 | BOOST_STATIC_CONSTANT(bool, value = true); |
71 | }; |
72 | |
73 | template<typename T> |
74 | struct is_basic_lockable<upgrade_lock<T> > |
75 | { |
76 | BOOST_STATIC_CONSTANT(bool, value = true); |
77 | }; |
78 | template<typename T> |
79 | struct is_lockable<upgrade_lock<T> > |
80 | { |
81 | BOOST_STATIC_CONSTANT(bool, value = true); |
82 | }; |
83 | |
84 | template<typename T> |
85 | struct is_basic_lockable<detail::try_lock_wrapper<T> > |
86 | { |
87 | BOOST_STATIC_CONSTANT(bool, value = true); |
88 | }; |
89 | template<typename T> |
90 | struct is_lockable<detail::try_lock_wrapper<T> > |
91 | { |
92 | BOOST_STATIC_CONSTANT(bool, value = true); |
93 | }; |
94 | } |
95 | #endif |
96 | |
97 | |
98 | template <typename Mutex> |
99 | class unique_lock |
100 | { |
101 | private: |
102 | Mutex* m; |
103 | bool is_locked; |
104 | |
105 | private: |
106 | explicit unique_lock(upgrade_lock<Mutex>&); |
107 | unique_lock& operator=(upgrade_lock<Mutex>& other); |
108 | public: |
109 | typedef Mutex mutex_type; |
110 | BOOST_THREAD_MOVABLE_ONLY( unique_lock) |
111 | |
112 | #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. |
113 | #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) |
114 | unique_lock(const volatile unique_lock&); |
115 | #endif |
116 | #endif |
117 | unique_lock()BOOST_NOEXCEPT : |
118 | m(0),is_locked(false) |
119 | {} |
120 | |
121 | explicit unique_lock(Mutex& m_) : |
122 | m(&m_), is_locked(false) |
123 | { |
124 | lock(); |
125 | } |
126 | unique_lock(Mutex& m_, adopt_lock_t) : |
127 | m(&m_), is_locked(true) |
128 | { |
129 | #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS |
130 | BOOST_ASSERT(is_locked_by_this_thread(m)); |
131 | #endif |
132 | } |
133 | unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT: |
134 | m(&m_),is_locked(false) |
135 | {} |
136 | unique_lock(Mutex& m_, try_to_lock_t) : |
137 | m(&m_), is_locked(false) |
138 | { |
139 | try_lock(); |
140 | } |
141 | #if defined BOOST_THREAD_USES_DATETIME |
142 | template<typename TimeDuration> |
143 | unique_lock(Mutex& m_,TimeDuration const& target_time): |
144 | m(&m_),is_locked(false) |
145 | { |
146 | timed_lock(target_time); |
147 | } |
148 | unique_lock(Mutex& m_,system_time const& target_time): |
149 | m(&m_),is_locked(false) |
150 | { |
151 | timed_lock(target_time); |
152 | } |
153 | #endif |
154 | #ifdef BOOST_THREAD_USES_CHRONO |
155 | template <class Clock, class Duration> |
156 | unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) |
157 | : m(&mtx), is_locked(mtx.try_lock_until(t)) |
158 | { |
159 | } |
160 | template <class Rep, class Period> |
161 | unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) |
162 | : m(&mtx), is_locked(mtx.try_lock_for(d)) |
163 | { |
164 | } |
165 | #endif |
166 | |
167 | unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT: |
168 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
169 | { |
170 | BOOST_THREAD_RV(other).is_locked=false; |
171 | BOOST_THREAD_RV(other).m=0; |
172 | } |
173 | |
174 | BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other); |
175 | |
176 | #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION |
177 | //std-2104 unique_lock move-assignment should not be noexcept |
178 | unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT |
179 | { |
180 | unique_lock temp(::boost::move(other)); |
181 | swap(temp); |
182 | return *this; |
183 | } |
184 | #endif |
185 | |
186 | //std-2104 unique_lock move-assignment should not be noexcept |
187 | unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT |
188 | { |
189 | unique_lock temp(::boost::move(other)); |
190 | swap(temp); |
191 | return *this; |
192 | } |
193 | #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. |
194 | #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) |
195 | unique_lock& operator=(unique_lock<Mutex> other) |
196 | { |
197 | swap(other); |
198 | return *this; |
199 | } |
200 | #endif // BOOST_WORKAROUND |
201 | #endif |
202 | |
203 | // Conversion from upgrade locking |
204 | unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t) |
205 | : m(0),is_locked(false) |
206 | { |
207 | if (BOOST_THREAD_RV(ul).owns_lock()) |
208 | { |
209 | if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock()) |
210 | { |
211 | m = BOOST_THREAD_RV(ul).release(); |
212 | is_locked = true; |
213 | } |
214 | } |
215 | else |
216 | { |
217 | m = BOOST_THREAD_RV(ul).release(); |
218 | } |
219 | } |
220 | |
221 | #ifdef BOOST_THREAD_USES_CHRONO |
222 | template <class Clock, class Duration> |
223 | unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, |
224 | const chrono::time_point<Clock, Duration>& abs_time) |
225 | : m(0),is_locked(false) |
226 | { |
227 | if (BOOST_THREAD_RV(ul).owns_lock()) |
228 | { |
229 | if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time)) |
230 | { |
231 | m = BOOST_THREAD_RV(ul).release(); |
232 | is_locked = true; |
233 | } |
234 | } |
235 | else |
236 | { |
237 | m = BOOST_THREAD_RV(ul).release(); |
238 | } |
239 | } |
240 | |
241 | template <class Rep, class Period> |
242 | unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, |
243 | const chrono::duration<Rep, Period>& rel_time) |
244 | : m(0),is_locked(false) |
245 | { |
246 | if (BOOST_THREAD_RV(ul).owns_lock()) |
247 | { |
248 | if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time)) |
249 | { |
250 | m = BOOST_THREAD_RV(ul).release(); |
251 | is_locked = true; |
252 | } |
253 | } |
254 | else |
255 | { |
256 | m = BOOST_THREAD_RV(ul).release(); |
257 | } |
258 | } |
259 | #endif |
260 | |
261 | #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
262 | // Conversion from shared locking |
263 | unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t) |
264 | : m(0),is_locked(false) |
265 | { |
266 | if (BOOST_THREAD_RV(sl).owns_lock()) |
267 | { |
268 | if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock()) |
269 | { |
270 | m = BOOST_THREAD_RV(sl).release(); |
271 | is_locked = true; |
272 | } |
273 | } |
274 | else |
275 | { |
276 | m = BOOST_THREAD_RV(sl).release(); |
277 | } |
278 | } |
279 | |
280 | #ifdef BOOST_THREAD_USES_CHRONO |
281 | template <class Clock, class Duration> |
282 | unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, |
283 | const chrono::time_point<Clock, Duration>& abs_time) |
284 | : m(0),is_locked(false) |
285 | { |
286 | if (BOOST_THREAD_RV(sl).owns_lock()) |
287 | { |
288 | if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time)) |
289 | { |
290 | m = BOOST_THREAD_RV(sl).release(); |
291 | is_locked = true; |
292 | } |
293 | } |
294 | else |
295 | { |
296 | m = BOOST_THREAD_RV(sl).release(); |
297 | } |
298 | } |
299 | |
300 | template <class Rep, class Period> |
301 | unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, |
302 | const chrono::duration<Rep, Period>& rel_time) |
303 | : m(0),is_locked(false) |
304 | { |
305 | if (BOOST_THREAD_RV(sl).owns_lock()) |
306 | { |
307 | if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time)) |
308 | { |
309 | m = BOOST_THREAD_RV(sl).release(); |
310 | is_locked = true; |
311 | } |
312 | } |
313 | else |
314 | { |
315 | m = BOOST_THREAD_RV(sl).release(); |
316 | } |
317 | } |
318 | #endif // BOOST_THREAD_USES_CHRONO |
319 | #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
320 | |
321 | void swap(unique_lock& other)BOOST_NOEXCEPT |
322 | { |
323 | std::swap(m,other.m); |
324 | std::swap(is_locked,other.is_locked); |
325 | } |
326 | |
327 | ~unique_lock() |
328 | { |
329 | if (owns_lock()) |
330 | { |
331 | m->unlock(); |
332 | } |
333 | } |
334 | void lock() |
335 | { |
336 | if (m == 0) |
337 | { |
338 | boost::throw_exception( |
339 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
340 | } |
341 | if (owns_lock()) |
342 | { |
343 | boost::throw_exception( |
344 | boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
345 | } |
346 | m->lock(); |
347 | is_locked = true; |
348 | } |
349 | bool try_lock() |
350 | { |
351 | if (m == 0) |
352 | { |
353 | boost::throw_exception( |
354 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
355 | } |
356 | if (owns_lock()) |
357 | { |
358 | boost::throw_exception( |
359 | boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
360 | } |
361 | is_locked = m->try_lock(); |
362 | return is_locked; |
363 | } |
364 | #if defined BOOST_THREAD_USES_DATETIME |
365 | template<typename TimeDuration> |
366 | bool timed_lock(TimeDuration const& relative_time) |
367 | { |
368 | if(m==0) |
369 | { |
370 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
371 | } |
372 | if(owns_lock()) |
373 | { |
374 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
375 | } |
376 | is_locked=m->timed_lock(relative_time); |
377 | return is_locked; |
378 | } |
379 | |
380 | bool timed_lock(::boost::system_time const& absolute_time) |
381 | { |
382 | if(m==0) |
383 | { |
384 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
385 | } |
386 | if(owns_lock()) |
387 | { |
388 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
389 | } |
390 | is_locked=m->timed_lock(absolute_time); |
391 | return is_locked; |
392 | } |
393 | bool timed_lock(::boost::xtime const& absolute_time) |
394 | { |
395 | if(m==0) |
396 | { |
397 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
398 | } |
399 | if(owns_lock()) |
400 | { |
401 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
402 | } |
403 | is_locked=m->timed_lock(absolute_time); |
404 | return is_locked; |
405 | } |
406 | #endif |
407 | #ifdef BOOST_THREAD_USES_CHRONO |
408 | |
409 | template <class Rep, class Period> |
410 | bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) |
411 | { |
412 | if(m==0) |
413 | { |
414 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
415 | } |
416 | if(owns_lock()) |
417 | { |
418 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
419 | } |
420 | is_locked=m->try_lock_for(rel_time); |
421 | return is_locked; |
422 | } |
423 | template <class Clock, class Duration> |
424 | bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) |
425 | { |
426 | if(m==0) |
427 | { |
428 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
429 | } |
430 | if(owns_lock()) |
431 | { |
432 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex" )); |
433 | } |
434 | is_locked=m->try_lock_until(abs_time); |
435 | return is_locked; |
436 | } |
437 | #endif |
438 | |
439 | void unlock() |
440 | { |
441 | if (m == 0) |
442 | { |
443 | boost::throw_exception( |
444 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex" )); |
445 | } |
446 | if (!owns_lock()) |
447 | { |
448 | boost::throw_exception( |
449 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock doesn't own the mutex" )); |
450 | } |
451 | m->unlock(); |
452 | is_locked = false; |
453 | } |
454 | |
455 | #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) |
456 | typedef void (unique_lock::*bool_type)(); |
457 | operator bool_type() const BOOST_NOEXCEPT |
458 | { |
459 | return is_locked?&unique_lock::lock:0; |
460 | } |
461 | bool operator!() const BOOST_NOEXCEPT |
462 | { |
463 | return !owns_lock(); |
464 | } |
465 | #else |
466 | explicit operator bool() const BOOST_NOEXCEPT |
467 | { |
468 | return owns_lock(); |
469 | } |
470 | #endif |
471 | bool owns_lock() const BOOST_NOEXCEPT |
472 | { |
473 | return is_locked; |
474 | } |
475 | |
476 | Mutex* mutex() const BOOST_NOEXCEPT |
477 | { |
478 | return m; |
479 | } |
480 | |
481 | Mutex* release()BOOST_NOEXCEPT |
482 | { |
483 | Mutex* const res=m; |
484 | m=0; |
485 | is_locked=false; |
486 | return res; |
487 | } |
488 | |
489 | friend class shared_lock<Mutex> ; |
490 | friend class upgrade_lock<Mutex> ; |
491 | }; |
492 | |
493 | template<typename Mutex> |
494 | void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs) |
495 | BOOST_NOEXCEPT |
496 | { |
497 | lhs.swap(rhs); |
498 | } |
499 | |
500 | BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END |
501 | |
502 | template<typename Mutex> |
503 | class shared_lock |
504 | { |
505 | protected: |
506 | Mutex* m; |
507 | bool is_locked; |
508 | |
509 | public: |
510 | typedef Mutex mutex_type; |
511 | BOOST_THREAD_MOVABLE_ONLY(shared_lock) |
512 | |
513 | shared_lock() BOOST_NOEXCEPT: |
514 | m(0),is_locked(false) |
515 | {} |
516 | |
517 | explicit shared_lock(Mutex& m_): |
518 | m(&m_),is_locked(false) |
519 | { |
520 | lock(); |
521 | } |
522 | shared_lock(Mutex& m_,adopt_lock_t): |
523 | m(&m_),is_locked(true) |
524 | { |
525 | #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS |
526 | BOOST_ASSERT(is_locked_by_this_thread(m)); |
527 | #endif |
528 | } |
529 | shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT: |
530 | m(&m_),is_locked(false) |
531 | {} |
532 | shared_lock(Mutex& m_,try_to_lock_t): |
533 | m(&m_),is_locked(false) |
534 | { |
535 | try_lock(); |
536 | } |
537 | #if defined BOOST_THREAD_USES_DATETIME |
538 | shared_lock(Mutex& m_,system_time const& target_time): |
539 | m(&m_),is_locked(false) |
540 | { |
541 | timed_lock(target_time); |
542 | } |
543 | #endif |
544 | #ifdef BOOST_THREAD_USES_CHRONO |
545 | template <class Clock, class Duration> |
546 | shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) |
547 | : m(&mtx), is_locked(mtx.try_lock_shared_until(t)) |
548 | { |
549 | } |
550 | template <class Rep, class Period> |
551 | shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) |
552 | : m(&mtx), is_locked(mtx.try_lock_shared_for(d)) |
553 | { |
554 | } |
555 | #endif |
556 | |
557 | shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: |
558 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
559 | { |
560 | BOOST_THREAD_RV(other).is_locked=false; |
561 | BOOST_THREAD_RV(other).m=0; |
562 | } |
563 | |
564 | BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other): |
565 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
566 | { |
567 | if(is_locked) |
568 | { |
569 | m->unlock_and_lock_shared(); |
570 | } |
571 | BOOST_THREAD_RV(other).is_locked=false; |
572 | BOOST_THREAD_RV(other).m=0; |
573 | } |
574 | |
575 | BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other): |
576 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
577 | { |
578 | if(is_locked) |
579 | { |
580 | m->unlock_upgrade_and_lock_shared(); |
581 | } |
582 | BOOST_THREAD_RV(other).is_locked=false; |
583 | BOOST_THREAD_RV(other).m=0; |
584 | } |
585 | |
586 | //std-2104 unique_lock move-assignment should not be noexcept |
587 | shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT |
588 | { |
589 | shared_lock temp(::boost::move(other)); |
590 | swap(temp); |
591 | return *this; |
592 | } |
593 | #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION |
594 | shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) |
595 | { |
596 | shared_lock temp(::boost::move(other)); |
597 | swap(temp); |
598 | return *this; |
599 | } |
600 | |
601 | shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) |
602 | { |
603 | shared_lock temp(::boost::move(other)); |
604 | swap(temp); |
605 | return *this; |
606 | } |
607 | #endif |
608 | |
609 | void swap(shared_lock& other) BOOST_NOEXCEPT |
610 | { |
611 | std::swap(m,other.m); |
612 | std::swap(is_locked,other.is_locked); |
613 | } |
614 | |
615 | Mutex* mutex() const BOOST_NOEXCEPT |
616 | { |
617 | return m; |
618 | } |
619 | |
620 | Mutex* release() BOOST_NOEXCEPT |
621 | { |
622 | Mutex* const res=m; |
623 | m=0; |
624 | is_locked=false; |
625 | return res; |
626 | } |
627 | |
628 | ~shared_lock() |
629 | { |
630 | if(owns_lock()) |
631 | { |
632 | m->unlock_shared(); |
633 | } |
634 | } |
635 | void lock() |
636 | { |
637 | if(m==0) |
638 | { |
639 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
640 | } |
641 | if(owns_lock()) |
642 | { |
643 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
644 | } |
645 | m->lock_shared(); |
646 | is_locked=true; |
647 | } |
648 | bool try_lock() |
649 | { |
650 | if(m==0) |
651 | { |
652 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
653 | } |
654 | if(owns_lock()) |
655 | { |
656 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
657 | } |
658 | is_locked=m->try_lock_shared(); |
659 | return is_locked; |
660 | } |
661 | #if defined BOOST_THREAD_USES_DATETIME |
662 | bool timed_lock(boost::system_time const& target_time) |
663 | { |
664 | if(m==0) |
665 | { |
666 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
667 | } |
668 | if(owns_lock()) |
669 | { |
670 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
671 | } |
672 | is_locked=m->timed_lock_shared(target_time); |
673 | return is_locked; |
674 | } |
675 | template<typename Duration> |
676 | bool timed_lock(Duration const& target_time) |
677 | { |
678 | if(m==0) |
679 | { |
680 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
681 | } |
682 | if(owns_lock()) |
683 | { |
684 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
685 | } |
686 | is_locked=m->timed_lock_shared(target_time); |
687 | return is_locked; |
688 | } |
689 | #endif |
690 | #ifdef BOOST_THREAD_USES_CHRONO |
691 | template <class Rep, class Period> |
692 | bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) |
693 | { |
694 | if(m==0) |
695 | { |
696 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
697 | } |
698 | if(owns_lock()) |
699 | { |
700 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
701 | } |
702 | is_locked=m->try_lock_shared_for(rel_time); |
703 | return is_locked; |
704 | } |
705 | template <class Clock, class Duration> |
706 | bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) |
707 | { |
708 | if(m==0) |
709 | { |
710 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
711 | } |
712 | if(owns_lock()) |
713 | { |
714 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
715 | } |
716 | is_locked=m->try_lock_shared_until(abs_time); |
717 | return is_locked; |
718 | } |
719 | #endif |
720 | void unlock() |
721 | { |
722 | if(m==0) |
723 | { |
724 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
725 | } |
726 | if(!owns_lock()) |
727 | { |
728 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock doesn't own the mutex" )); |
729 | } |
730 | m->unlock_shared(); |
731 | is_locked=false; |
732 | } |
733 | |
734 | #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) |
735 | typedef void (shared_lock<Mutex>::*bool_type)(); |
736 | operator bool_type() const BOOST_NOEXCEPT |
737 | { |
738 | return is_locked?&shared_lock::lock:0; |
739 | } |
740 | bool operator!() const BOOST_NOEXCEPT |
741 | { |
742 | return !owns_lock(); |
743 | } |
744 | #else |
745 | explicit operator bool() const BOOST_NOEXCEPT |
746 | { |
747 | return owns_lock(); |
748 | } |
749 | #endif |
750 | bool owns_lock() const BOOST_NOEXCEPT |
751 | { |
752 | return is_locked; |
753 | } |
754 | |
755 | }; |
756 | |
757 | BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END |
758 | |
759 | template<typename Mutex> |
760 | void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT |
761 | { |
762 | lhs.swap(rhs); |
763 | } |
764 | |
765 | template <typename Mutex> |
766 | class upgrade_lock |
767 | { |
768 | protected: |
769 | Mutex* m; |
770 | bool is_locked; |
771 | |
772 | public: |
773 | typedef Mutex mutex_type; |
774 | BOOST_THREAD_MOVABLE_ONLY( upgrade_lock) |
775 | |
776 | upgrade_lock()BOOST_NOEXCEPT: |
777 | m(0),is_locked(false) |
778 | {} |
779 | |
780 | explicit upgrade_lock(Mutex& m_) : |
781 | m(&m_), is_locked(false) |
782 | { |
783 | lock(); |
784 | } |
785 | upgrade_lock(Mutex& m_, adopt_lock_t) : |
786 | m(&m_), is_locked(true) |
787 | { |
788 | #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS |
789 | BOOST_ASSERT(is_locked_by_this_thread(m)); |
790 | #endif |
791 | } |
792 | upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT: |
793 | m(&m_),is_locked(false) |
794 | {} |
795 | upgrade_lock(Mutex& m_, try_to_lock_t) : |
796 | m(&m_), is_locked(false) |
797 | { |
798 | try_lock(); |
799 | } |
800 | |
801 | #ifdef BOOST_THREAD_USES_CHRONO |
802 | template <class Clock, class Duration> |
803 | upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) |
804 | : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t)) |
805 | { |
806 | } |
807 | template <class Rep, class Period> |
808 | upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) |
809 | : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d)) |
810 | { |
811 | } |
812 | #endif |
813 | |
814 | upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: |
815 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
816 | { |
817 | BOOST_THREAD_RV(other).is_locked=false; |
818 | BOOST_THREAD_RV(other).m=0; |
819 | } |
820 | |
821 | BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other): |
822 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
823 | { |
824 | if(is_locked) |
825 | { |
826 | m->unlock_and_lock_upgrade(); |
827 | } |
828 | BOOST_THREAD_RV(other).is_locked=false; |
829 | BOOST_THREAD_RV(other).m=0; |
830 | } |
831 | |
832 | //std-2104 unique_lock move-assignment should not be noexcept |
833 | upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT |
834 | { |
835 | upgrade_lock temp(::boost::move(other)); |
836 | swap(temp); |
837 | return *this; |
838 | } |
839 | |
840 | #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION |
841 | upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) |
842 | { |
843 | upgrade_lock temp(::boost::move(other)); |
844 | swap(temp); |
845 | return *this; |
846 | } |
847 | #endif |
848 | |
849 | #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
850 | // Conversion from shared locking |
851 | upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t) |
852 | : m(0),is_locked(false) |
853 | { |
854 | if (BOOST_THREAD_RV(sl).owns_lock()) |
855 | { |
856 | if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade()) |
857 | { |
858 | m = BOOST_THREAD_RV(sl).release(); |
859 | is_locked = true; |
860 | } |
861 | } |
862 | else |
863 | { |
864 | m = BOOST_THREAD_RV(sl).release(); |
865 | } |
866 | } |
867 | |
868 | #ifdef BOOST_THREAD_USES_CHRONO |
869 | template <class Clock, class Duration> |
870 | upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, |
871 | const chrono::time_point<Clock, Duration>& abs_time) |
872 | : m(0),is_locked(false) |
873 | { |
874 | if (BOOST_THREAD_RV(sl).owns_lock()) |
875 | { |
876 | if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time)) |
877 | { |
878 | m = BOOST_THREAD_RV(sl).release(); |
879 | is_locked = true; |
880 | } |
881 | } |
882 | else |
883 | { |
884 | m = BOOST_THREAD_RV(sl).release(); |
885 | } |
886 | } |
887 | |
888 | template <class Rep, class Period> |
889 | upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, |
890 | const chrono::duration<Rep, Period>& rel_time) |
891 | : m(0),is_locked(false) |
892 | { |
893 | if (BOOST_THREAD_RV(sl).owns_lock()) |
894 | { |
895 | if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time)) |
896 | { |
897 | m = BOOST_THREAD_RV(sl).release(); |
898 | is_locked = true; |
899 | } |
900 | } |
901 | else |
902 | { |
903 | m = BOOST_THREAD_RV(sl).release(); |
904 | } |
905 | } |
906 | #endif // BOOST_THREAD_USES_CHRONO |
907 | #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
908 | void swap(upgrade_lock& other)BOOST_NOEXCEPT |
909 | { |
910 | std::swap(m,other.m); |
911 | std::swap(is_locked,other.is_locked); |
912 | } |
913 | Mutex* mutex() const BOOST_NOEXCEPT |
914 | { |
915 | return m; |
916 | } |
917 | |
918 | Mutex* release()BOOST_NOEXCEPT |
919 | { |
920 | Mutex* const res=m; |
921 | m=0; |
922 | is_locked=false; |
923 | return res; |
924 | } |
925 | ~upgrade_lock() |
926 | { |
927 | if (owns_lock()) |
928 | { |
929 | m->unlock_upgrade(); |
930 | } |
931 | } |
932 | void lock() |
933 | { |
934 | if (m == 0) |
935 | { |
936 | boost::throw_exception( |
937 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
938 | } |
939 | if (owns_lock()) |
940 | { |
941 | boost::throw_exception( |
942 | boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex" )); |
943 | } |
944 | m->lock_upgrade(); |
945 | is_locked = true; |
946 | } |
947 | bool try_lock() |
948 | { |
949 | if (m == 0) |
950 | { |
951 | boost::throw_exception( |
952 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
953 | } |
954 | if (owns_lock()) |
955 | { |
956 | boost::throw_exception( |
957 | boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex" )); |
958 | } |
959 | is_locked = m->try_lock_upgrade(); |
960 | return is_locked; |
961 | } |
962 | void unlock() |
963 | { |
964 | if (m == 0) |
965 | { |
966 | boost::throw_exception( |
967 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
968 | } |
969 | if (!owns_lock()) |
970 | { |
971 | boost::throw_exception( |
972 | boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock doesn't own the mutex" )); |
973 | } |
974 | m->unlock_upgrade(); |
975 | is_locked = false; |
976 | } |
977 | #ifdef BOOST_THREAD_USES_CHRONO |
978 | template <class Rep, class Period> |
979 | bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) |
980 | { |
981 | if(m==0) |
982 | { |
983 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
984 | } |
985 | if(owns_lock()) |
986 | { |
987 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
988 | } |
989 | is_locked=m->try_lock_upgrade_for(rel_time); |
990 | return is_locked; |
991 | } |
992 | template <class Clock, class Duration> |
993 | bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) |
994 | { |
995 | if(m==0) |
996 | { |
997 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex" )); |
998 | } |
999 | if(owns_lock()) |
1000 | { |
1001 | boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex" )); |
1002 | } |
1003 | is_locked=m->try_lock_upgrade_until(abs_time); |
1004 | return is_locked; |
1005 | } |
1006 | #endif |
1007 | #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) |
1008 | typedef void (upgrade_lock::*bool_type)(); |
1009 | operator bool_type() const BOOST_NOEXCEPT |
1010 | { |
1011 | return is_locked?&upgrade_lock::lock:0; |
1012 | } |
1013 | bool operator!() const BOOST_NOEXCEPT |
1014 | { |
1015 | return !owns_lock(); |
1016 | } |
1017 | #else |
1018 | explicit operator bool() const BOOST_NOEXCEPT |
1019 | { |
1020 | return owns_lock(); |
1021 | } |
1022 | #endif |
1023 | bool owns_lock() const BOOST_NOEXCEPT |
1024 | { |
1025 | return is_locked; |
1026 | } |
1027 | friend class shared_lock<Mutex> ; |
1028 | friend class unique_lock<Mutex> ; |
1029 | }; |
1030 | |
1031 | template<typename Mutex> |
1032 | void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs) |
1033 | BOOST_NOEXCEPT |
1034 | { |
1035 | lhs.swap(rhs); |
1036 | } |
1037 | |
1038 | BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END |
1039 | |
1040 | template<typename Mutex> |
1041 | unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other): |
1042 | m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) |
1043 | { |
1044 | if(is_locked) |
1045 | { |
1046 | m->unlock_upgrade_and_lock(); |
1047 | } |
1048 | BOOST_THREAD_RV(other).release(); |
1049 | } |
1050 | |
1051 | template <class Mutex> |
1052 | class upgrade_to_unique_lock |
1053 | { |
1054 | private: |
1055 | upgrade_lock<Mutex>* source; |
1056 | unique_lock<Mutex> exclusive; |
1057 | |
1058 | public: |
1059 | typedef Mutex mutex_type; |
1060 | BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock) |
1061 | |
1062 | explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) : |
1063 | source(&m_), exclusive(::boost::move(*source)) |
1064 | { |
1065 | } |
1066 | ~upgrade_to_unique_lock() |
1067 | { |
1068 | if (source) |
1069 | { |
1070 | *source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive))); |
1071 | } |
1072 | } |
1073 | |
1074 | upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: |
1075 | source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive)) |
1076 | { |
1077 | BOOST_THREAD_RV(other).source=0; |
1078 | } |
1079 | |
1080 | //std-2104 unique_lock move-assignment should not be noexcept |
1081 | upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT |
1082 | { |
1083 | upgrade_to_unique_lock temp(other); |
1084 | swap(temp); |
1085 | return *this; |
1086 | } |
1087 | |
1088 | void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT |
1089 | { |
1090 | std::swap(source,other.source); |
1091 | exclusive.swap(other.exclusive); |
1092 | } |
1093 | |
1094 | #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) |
1095 | typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&); |
1096 | operator bool_type() const BOOST_NOEXCEPT |
1097 | { |
1098 | return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0; |
1099 | } |
1100 | bool operator!() const BOOST_NOEXCEPT |
1101 | { |
1102 | return !owns_lock(); |
1103 | } |
1104 | #else |
1105 | explicit operator bool() const BOOST_NOEXCEPT |
1106 | { |
1107 | return owns_lock(); |
1108 | } |
1109 | #endif |
1110 | |
1111 | bool owns_lock() const BOOST_NOEXCEPT |
1112 | { |
1113 | return exclusive.owns_lock(); |
1114 | } |
1115 | Mutex* mutex() const BOOST_NOEXCEPT |
1116 | { |
1117 | return exclusive.mutex(); |
1118 | } |
1119 | }; |
1120 | |
1121 | BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END |
1122 | |
1123 | namespace detail |
1124 | { |
1125 | template<typename Mutex> |
1126 | class try_lock_wrapper: |
1127 | private unique_lock<Mutex> |
1128 | { |
1129 | typedef unique_lock<Mutex> base; |
1130 | public: |
1131 | BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper) |
1132 | |
1133 | try_lock_wrapper() |
1134 | {} |
1135 | |
1136 | explicit try_lock_wrapper(Mutex& m): |
1137 | base(m,try_to_lock) |
1138 | {} |
1139 | |
1140 | try_lock_wrapper(Mutex& m_,adopt_lock_t): |
1141 | base(m_,adopt_lock) |
1142 | { |
1143 | #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS |
1144 | BOOST_ASSERT(is_locked_by_this_thread(m_)); |
1145 | #endif |
1146 | } |
1147 | try_lock_wrapper(Mutex& m_,defer_lock_t): |
1148 | base(m_,defer_lock) |
1149 | {} |
1150 | try_lock_wrapper(Mutex& m_,try_to_lock_t): |
1151 | base(m_,try_to_lock) |
1152 | {} |
1153 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
1154 | try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): |
1155 | base(::boost::move(other)) |
1156 | {} |
1157 | |
1158 | #elif defined BOOST_THREAD_USES_MOVE |
1159 | try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): |
1160 | base(::boost::move(static_cast<base&>(other))) |
1161 | {} |
1162 | |
1163 | #else |
1164 | try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): |
1165 | base(BOOST_THREAD_RV_REF(base)(*other)) |
1166 | {} |
1167 | #endif |
1168 | try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other) |
1169 | { |
1170 | try_lock_wrapper temp(other); |
1171 | swap(temp); |
1172 | return *this; |
1173 | } |
1174 | void swap(try_lock_wrapper& other) |
1175 | { |
1176 | base::swap(other); |
1177 | } |
1178 | void lock() |
1179 | { |
1180 | base::lock(); |
1181 | } |
1182 | bool try_lock() |
1183 | { |
1184 | return base::try_lock(); |
1185 | } |
1186 | void unlock() |
1187 | { |
1188 | base::unlock(); |
1189 | } |
1190 | bool owns_lock() const |
1191 | { |
1192 | return base::owns_lock(); |
1193 | } |
1194 | Mutex* mutex() const BOOST_NOEXCEPT |
1195 | { |
1196 | return base::mutex(); |
1197 | } |
1198 | Mutex* release() |
1199 | { |
1200 | return base::release(); |
1201 | } |
1202 | |
1203 | #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) |
1204 | typedef typename base::bool_type bool_type; |
1205 | operator bool_type() const |
1206 | { |
1207 | return base::operator bool_type(); |
1208 | } |
1209 | bool operator!() const |
1210 | { |
1211 | return !this->owns_lock(); |
1212 | } |
1213 | #else |
1214 | explicit operator bool() const |
1215 | { |
1216 | return owns_lock(); |
1217 | } |
1218 | #endif |
1219 | }; |
1220 | |
1221 | template<typename Mutex> |
1222 | void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs) |
1223 | { |
1224 | lhs.swap(rhs); |
1225 | } |
1226 | } |
1227 | } |
1228 | #include <boost/config/abi_suffix.hpp> |
1229 | |
1230 | #endif |
1231 | |