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
7 #ifndef BOOST_THREAD_LOCK_TYPES_HPP
8 #define BOOST_THREAD_LOCK_TYPES_HPP
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>
18 #include <boost/thread/thread_time.hpp>
20 #include <boost/assert.hpp>
21 #ifdef BOOST_THREAD_USES_CHRONO
22 #include <boost/chrono/time_point.hpp>
23 #include <boost/chrono/duration.hpp>
25 #include <boost/detail/workaround.hpp>
27 #include <boost/config/abi_prefix.hpp>
33 template <typename Mutex>
36 template <typename Mutex>
39 template <typename Mutex>
44 template <typename Mutex>
45 class try_lock_wrapper;
48 #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
52 struct is_basic_lockable<unique_lock<T> >
54 BOOST_STATIC_CONSTANT(bool, value = true);
57 struct is_lockable<unique_lock<T> >
59 BOOST_STATIC_CONSTANT(bool, value = true);
63 struct is_basic_lockable<shared_lock<T> >
65 BOOST_STATIC_CONSTANT(bool, value = true);
68 struct is_lockable<shared_lock<T> >
70 BOOST_STATIC_CONSTANT(bool, value = true);
74 struct is_basic_lockable<upgrade_lock<T> >
76 BOOST_STATIC_CONSTANT(bool, value = true);
79 struct is_lockable<upgrade_lock<T> >
81 BOOST_STATIC_CONSTANT(bool, value = true);
85 struct is_basic_lockable<detail::try_lock_wrapper<T> >
87 BOOST_STATIC_CONSTANT(bool, value = true);
90 struct is_lockable<detail::try_lock_wrapper<T> >
92 BOOST_STATIC_CONSTANT(bool, value = true);
98 template <typename Mutex>
106 explicit unique_lock(upgrade_lock<Mutex>&);
107 unique_lock& operator=(upgrade_lock<Mutex>& other);
109 typedef Mutex mutex_type;
110 BOOST_THREAD_MOVABLE_ONLY( unique_lock)
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&);
117 unique_lock()BOOST_NOEXCEPT :
118 m(0),is_locked(false)
121 explicit unique_lock(Mutex& m_) :
122 m(&m_), is_locked(false)
126 unique_lock(Mutex& m_, adopt_lock_t) :
127 m(&m_), is_locked(true)
129 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
130 BOOST_ASSERT(is_locked_by_this_thread(m));
133 unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
134 m(&m_),is_locked(false)
136 unique_lock(Mutex& m_, try_to_lock_t) :
137 m(&m_), is_locked(false)
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)
146 timed_lock(target_time);
148 unique_lock(Mutex& m_,system_time const& target_time):
149 m(&m_),is_locked(false)
151 timed_lock(target_time);
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))
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))
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)
170 BOOST_THREAD_RV(other).is_locked=false;
171 BOOST_THREAD_RV(other).m=0;
174 BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other);
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
180 unique_lock temp(::boost::move(other));
186 //std-2104 unique_lock move-assignment should not be noexcept
187 unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT
189 unique_lock temp(::boost::move(other));
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)
200 #endif // BOOST_WORKAROUND
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)
207 if (BOOST_THREAD_RV(ul).owns_lock())
209 if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock())
211 m = BOOST_THREAD_RV(ul).release();
217 m = BOOST_THREAD_RV(ul).release();
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)
227 if (BOOST_THREAD_RV(ul).owns_lock())
229 if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time))
231 m = BOOST_THREAD_RV(ul).release();
237 m = BOOST_THREAD_RV(ul).release();
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)
246 if (BOOST_THREAD_RV(ul).owns_lock())
248 if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time))
250 m = BOOST_THREAD_RV(ul).release();
256 m = BOOST_THREAD_RV(ul).release();
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)
266 if (BOOST_THREAD_RV(sl).owns_lock())
268 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock())
270 m = BOOST_THREAD_RV(sl).release();
276 m = BOOST_THREAD_RV(sl).release();
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)
286 if (BOOST_THREAD_RV(sl).owns_lock())
288 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time))
290 m = BOOST_THREAD_RV(sl).release();
296 m = BOOST_THREAD_RV(sl).release();
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)
305 if (BOOST_THREAD_RV(sl).owns_lock())
307 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time))
309 m = BOOST_THREAD_RV(sl).release();
315 m = BOOST_THREAD_RV(sl).release();
318 #endif // BOOST_THREAD_USES_CHRONO
319 #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
321 void swap(unique_lock& other)BOOST_NOEXCEPT
323 std::swap(m,other.m);
324 std::swap(is_locked,other.is_locked);
338 boost::throw_exception(
339 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
343 boost::throw_exception(
344 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
353 boost::throw_exception(
354 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
358 boost::throw_exception(
359 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
361 is_locked = m->try_lock();
364 #if defined BOOST_THREAD_USES_DATETIME
365 template<typename TimeDuration>
366 bool timed_lock(TimeDuration const& relative_time)
370 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
374 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
376 is_locked=m->timed_lock(relative_time);
380 bool timed_lock(::boost::system_time const& absolute_time)
384 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
388 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
390 is_locked=m->timed_lock(absolute_time);
393 bool timed_lock(::boost::xtime const& absolute_time)
397 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
401 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
403 is_locked=m->timed_lock(absolute_time);
407 #ifdef BOOST_THREAD_USES_CHRONO
409 template <class Rep, class Period>
410 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
414 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
418 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
420 is_locked=m->try_lock_for(rel_time);
423 template <class Clock, class Duration>
424 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
428 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
432 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
434 is_locked=m->try_lock_until(abs_time);
443 boost::throw_exception(
444 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
448 boost::throw_exception(
449 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock doesn't own the mutex"));
455 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
456 typedef void (unique_lock::*bool_type)();
457 operator bool_type() const BOOST_NOEXCEPT
459 return is_locked?&unique_lock::lock:0;
461 bool operator!() const BOOST_NOEXCEPT
466 explicit operator bool() const BOOST_NOEXCEPT
471 bool owns_lock() const BOOST_NOEXCEPT
476 Mutex* mutex() const BOOST_NOEXCEPT
481 Mutex* release()BOOST_NOEXCEPT
489 friend class shared_lock<Mutex> ;
490 friend class upgrade_lock<Mutex> ;
493 template<typename Mutex>
494 void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs)
500 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
502 template<typename Mutex>
510 typedef Mutex mutex_type;
511 BOOST_THREAD_MOVABLE_ONLY(shared_lock)
513 shared_lock() BOOST_NOEXCEPT:
514 m(0),is_locked(false)
517 explicit shared_lock(Mutex& m_):
518 m(&m_),is_locked(false)
522 shared_lock(Mutex& m_,adopt_lock_t):
523 m(&m_),is_locked(true)
525 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
526 BOOST_ASSERT(is_locked_by_this_thread(m));
529 shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
530 m(&m_),is_locked(false)
532 shared_lock(Mutex& m_,try_to_lock_t):
533 m(&m_),is_locked(false)
537 #if defined BOOST_THREAD_USES_DATETIME
538 shared_lock(Mutex& m_,system_time const& target_time):
539 m(&m_),is_locked(false)
541 timed_lock(target_time);
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))
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))
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)
560 BOOST_THREAD_RV(other).is_locked=false;
561 BOOST_THREAD_RV(other).m=0;
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)
569 m->unlock_and_lock_shared();
571 BOOST_THREAD_RV(other).is_locked=false;
572 BOOST_THREAD_RV(other).m=0;
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)
580 m->unlock_upgrade_and_lock_shared();
582 BOOST_THREAD_RV(other).is_locked=false;
583 BOOST_THREAD_RV(other).m=0;
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
589 shared_lock temp(::boost::move(other));
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)
596 shared_lock temp(::boost::move(other));
601 shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)
603 shared_lock temp(::boost::move(other));
609 void swap(shared_lock& other) BOOST_NOEXCEPT
611 std::swap(m,other.m);
612 std::swap(is_locked,other.is_locked);
615 Mutex* mutex() const BOOST_NOEXCEPT
620 Mutex* release() BOOST_NOEXCEPT
639 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
643 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
652 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
656 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
658 is_locked=m->try_lock_shared();
661 #if defined BOOST_THREAD_USES_DATETIME
662 bool timed_lock(boost::system_time const& target_time)
666 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
670 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
672 is_locked=m->timed_lock_shared(target_time);
675 template<typename Duration>
676 bool timed_lock(Duration const& target_time)
680 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
684 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
686 is_locked=m->timed_lock_shared(target_time);
690 #ifdef BOOST_THREAD_USES_CHRONO
691 template <class Rep, class Period>
692 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
696 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
700 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
702 is_locked=m->try_lock_shared_for(rel_time);
705 template <class Clock, class Duration>
706 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
710 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
714 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
716 is_locked=m->try_lock_shared_until(abs_time);
724 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
728 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock doesn't own the mutex"));
734 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
735 typedef void (shared_lock<Mutex>::*bool_type)();
736 operator bool_type() const BOOST_NOEXCEPT
738 return is_locked?&shared_lock::lock:0;
740 bool operator!() const BOOST_NOEXCEPT
745 explicit operator bool() const BOOST_NOEXCEPT
750 bool owns_lock() const BOOST_NOEXCEPT
757 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
759 template<typename Mutex>
760 void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
765 template <typename Mutex>
773 typedef Mutex mutex_type;
774 BOOST_THREAD_MOVABLE_ONLY( upgrade_lock)
776 upgrade_lock()BOOST_NOEXCEPT:
777 m(0),is_locked(false)
780 explicit upgrade_lock(Mutex& m_) :
781 m(&m_), is_locked(false)
785 upgrade_lock(Mutex& m_, adopt_lock_t) :
786 m(&m_), is_locked(true)
788 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
789 BOOST_ASSERT(is_locked_by_this_thread(m));
792 upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
793 m(&m_),is_locked(false)
795 upgrade_lock(Mutex& m_, try_to_lock_t) :
796 m(&m_), is_locked(false)
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))
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))
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)
817 BOOST_THREAD_RV(other).is_locked=false;
818 BOOST_THREAD_RV(other).m=0;
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)
826 m->unlock_and_lock_upgrade();
828 BOOST_THREAD_RV(other).is_locked=false;
829 BOOST_THREAD_RV(other).m=0;
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
835 upgrade_lock temp(::boost::move(other));
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)
843 upgrade_lock temp(::boost::move(other));
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)
854 if (BOOST_THREAD_RV(sl).owns_lock())
856 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())
858 m = BOOST_THREAD_RV(sl).release();
864 m = BOOST_THREAD_RV(sl).release();
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)
874 if (BOOST_THREAD_RV(sl).owns_lock())
876 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
878 m = BOOST_THREAD_RV(sl).release();
884 m = BOOST_THREAD_RV(sl).release();
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)
893 if (BOOST_THREAD_RV(sl).owns_lock())
895 if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
897 m = BOOST_THREAD_RV(sl).release();
903 m = BOOST_THREAD_RV(sl).release();
906 #endif // BOOST_THREAD_USES_CHRONO
907 #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
908 void swap(upgrade_lock& other)BOOST_NOEXCEPT
910 std::swap(m,other.m);
911 std::swap(is_locked,other.is_locked);
913 Mutex* mutex() const BOOST_NOEXCEPT
918 Mutex* release()BOOST_NOEXCEPT
936 boost::throw_exception(
937 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
941 boost::throw_exception(
942 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
951 boost::throw_exception(
952 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
956 boost::throw_exception(
957 boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
959 is_locked = m->try_lock_upgrade();
966 boost::throw_exception(
967 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
971 boost::throw_exception(
972 boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock doesn't own the mutex"));
977 #ifdef BOOST_THREAD_USES_CHRONO
978 template <class Rep, class Period>
979 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
983 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
987 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
989 is_locked=m->try_lock_upgrade_for(rel_time);
992 template <class Clock, class Duration>
993 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
997 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
1001 boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
1003 is_locked=m->try_lock_upgrade_until(abs_time);
1007 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
1008 typedef void (upgrade_lock::*bool_type)();
1009 operator bool_type() const BOOST_NOEXCEPT
1011 return is_locked?&upgrade_lock::lock:0;
1013 bool operator!() const BOOST_NOEXCEPT
1015 return !owns_lock();
1018 explicit operator bool() const BOOST_NOEXCEPT
1023 bool owns_lock() const BOOST_NOEXCEPT
1027 friend class shared_lock<Mutex> ;
1028 friend class unique_lock<Mutex> ;
1031 template<typename Mutex>
1032 void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs)
1038 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
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)
1046 m->unlock_upgrade_and_lock();
1048 BOOST_THREAD_RV(other).release();
1051 template <class Mutex>
1052 class upgrade_to_unique_lock
1055 upgrade_lock<Mutex>* source;
1056 unique_lock<Mutex> exclusive;
1059 typedef Mutex mutex_type;
1060 BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock)
1062 explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) :
1063 source(&m_), exclusive(::boost::move(*source))
1066 ~upgrade_to_unique_lock()
1070 *source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive)));
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))
1077 BOOST_THREAD_RV(other).source=0;
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
1083 upgrade_to_unique_lock temp(::boost::move(other));
1088 void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT
1090 std::swap(source,other.source);
1091 exclusive.swap(other.exclusive);
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
1098 return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
1100 bool operator!() const BOOST_NOEXCEPT
1102 return !owns_lock();
1105 explicit operator bool() const BOOST_NOEXCEPT
1111 bool owns_lock() const BOOST_NOEXCEPT
1113 return exclusive.owns_lock();
1115 Mutex* mutex() const BOOST_NOEXCEPT
1117 return exclusive.mutex();
1121 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
1125 template<typename Mutex>
1126 class try_lock_wrapper:
1127 private unique_lock<Mutex>
1129 typedef unique_lock<Mutex> base;
1131 BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper)
1136 explicit try_lock_wrapper(Mutex& m):
1140 try_lock_wrapper(Mutex& m_,adopt_lock_t):
1143 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
1144 BOOST_ASSERT(is_locked_by_this_thread(m_));
1147 try_lock_wrapper(Mutex& m_,defer_lock_t):
1150 try_lock_wrapper(Mutex& m_,try_to_lock_t):
1151 base(m_,try_to_lock)
1153 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1154 try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1155 base(::boost::move(other))
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)))
1164 try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1165 base(BOOST_THREAD_RV_REF(base)(*other))
1168 try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
1170 try_lock_wrapper temp(::boost::move(other));
1174 void swap(try_lock_wrapper& other)
1184 return base::try_lock();
1190 bool owns_lock() const
1192 return base::owns_lock();
1194 Mutex* mutex() const BOOST_NOEXCEPT
1196 return base::mutex();
1200 return base::release();
1203 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
1204 typedef typename base::bool_type bool_type;
1205 operator bool_type() const
1207 return base::operator bool_type();
1209 bool operator!() const
1211 return !this->owns_lock();
1214 explicit operator bool() const
1221 template<typename Mutex>
1222 void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
1228 #include <boost/config/abi_suffix.hpp>