• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
unique_lock()117     unique_lock()BOOST_NOEXCEPT :
118     m(0),is_locked(false)
119     {}
120 
unique_lock(Mutex & m_)121     explicit unique_lock(Mutex& m_) :
122       m(&m_), is_locked(false)
123     {
124       lock();
125     }
unique_lock(Mutex & m_,adopt_lock_t)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     }
unique_lock(Mutex & m_,defer_lock_t)133     unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
134     m(&m_),is_locked(false)
135     {}
unique_lock(Mutex & m_,try_to_lock_t)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>
unique_lock(Mutex & m_,TimeDuration const & target_time)143     unique_lock(Mutex& m_,TimeDuration const& target_time):
144     m(&m_),is_locked(false)
145     {
146       timed_lock(target_time);
147     }
unique_lock(Mutex & m_,system_time const & target_time)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>
unique_lock(Mutex & mtx,const chrono::time_point<Clock,Duration> & t)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>
unique_lock(Mutex & mtx,const chrono::duration<Rep,Period> & d)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 
unique_lock(BOOST_THREAD_RV_REF (unique_lock)other)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
operator =(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
operator =(BOOST_THREAD_RV_REF (unique_lock)other)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
unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,try_to_lock_t)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>
unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,const chrono::time_point<Clock,Duration> & abs_time)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>
unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,const chrono::duration<Rep,Period> & rel_time)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
unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,try_to_lock_t)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>
unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::time_point<Clock,Duration> & abs_time)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>
unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::duration<Rep,Period> & rel_time)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 
swap(unique_lock & other)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 
~unique_lock()327     ~unique_lock()
328     {
329       if (owns_lock())
330       {
331         m->unlock();
332       }
333     }
lock()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     }
try_lock()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>
timed_lock(TimeDuration const & relative_time)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 
timed_lock(::boost::system_time const & absolute_time)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     }
timed_lock(::boost::xtime const & absolute_time)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>
try_lock_for(const chrono::duration<Rep,Period> & rel_time)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>
try_lock_until(const chrono::time_point<Clock,Duration> & abs_time)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 
unlock()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)();
operator bool_type() const457     operator bool_type() const BOOST_NOEXCEPT
458     {
459       return is_locked?&unique_lock::lock:0;
460     }
operator !() const461     bool operator!() const BOOST_NOEXCEPT
462     {
463       return !owns_lock();
464     }
465 #else
operator bool() const466     explicit operator bool() const BOOST_NOEXCEPT
467     {
468       return owns_lock();
469     }
470 #endif
owns_lock() const471     bool owns_lock() const BOOST_NOEXCEPT
472     {
473       return is_locked;
474     }
475 
mutex() const476     Mutex* mutex() const BOOST_NOEXCEPT
477     {
478       return m;
479     }
480 
release()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>
swap(unique_lock<Mutex> & lhs,unique_lock<Mutex> & rhs)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 
shared_lock()513     shared_lock() BOOST_NOEXCEPT:
514     m(0),is_locked(false)
515     {}
516 
shared_lock(Mutex & m_)517     explicit shared_lock(Mutex& m_):
518     m(&m_),is_locked(false)
519     {
520       lock();
521     }
shared_lock(Mutex & m_,adopt_lock_t)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     }
shared_lock(Mutex & m_,defer_lock_t)529     shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
530     m(&m_),is_locked(false)
531     {}
shared_lock(Mutex & m_,try_to_lock_t)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
shared_lock(Mutex & m_,system_time const & target_time)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>
shared_lock(Mutex & mtx,const chrono::time_point<Clock,Duration> & t)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>
shared_lock(Mutex & mtx,const chrono::duration<Rep,Period> & d)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 
shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other)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 
shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)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 
shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
operator =(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
operator =(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)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 
operator =(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)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 
swap(shared_lock & other)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 
mutex() const615     Mutex* mutex() const BOOST_NOEXCEPT
616     {
617       return m;
618     }
619 
release()620     Mutex* release() BOOST_NOEXCEPT
621     {
622       Mutex* const res=m;
623       m=0;
624       is_locked=false;
625       return res;
626     }
627 
~shared_lock()628     ~shared_lock()
629     {
630       if(owns_lock())
631       {
632         m->unlock_shared();
633       }
634     }
lock()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     }
try_lock()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
timed_lock(boost::system_time const & target_time)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>
timed_lock(Duration const & target_time)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>
try_lock_for(const chrono::duration<Rep,Period> & rel_time)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>
try_lock_until(const chrono::time_point<Clock,Duration> & abs_time)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
unlock()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)();
operator bool_type() const736     operator bool_type() const BOOST_NOEXCEPT
737     {
738       return is_locked?&shared_lock::lock:0;
739     }
operator !() const740     bool operator!() const BOOST_NOEXCEPT
741     {
742       return !owns_lock();
743     }
744 #else
operator bool() const745     explicit operator bool() const BOOST_NOEXCEPT
746     {
747       return owns_lock();
748     }
749 #endif
owns_lock() const750     bool owns_lock() const BOOST_NOEXCEPT
751     {
752       return is_locked;
753     }
754 
755   };
756 
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex)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 
upgrade_lock()776     upgrade_lock()BOOST_NOEXCEPT:
777     m(0),is_locked(false)
778     {}
779 
upgrade_lock(Mutex & m_)780     explicit upgrade_lock(Mutex& m_) :
781       m(&m_), is_locked(false)
782     {
783       lock();
784     }
upgrade_lock(Mutex & m_,adopt_lock_t)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     }
upgrade_lock(Mutex & m_,defer_lock_t)792     upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
793     m(&m_),is_locked(false)
794     {}
upgrade_lock(Mutex & m_,try_to_lock_t)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>
upgrade_lock(Mutex & mtx,const chrono::time_point<Clock,Duration> & t)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>
upgrade_lock(Mutex & mtx,const chrono::duration<Rep,Period> & d)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 
upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)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 
upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
operator =(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
operator =(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,try_to_lock_t)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>
upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::time_point<Clock,Duration> & abs_time)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>
upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,const chrono::duration<Rep,Period> & rel_time)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
swap(upgrade_lock & other)908     void swap(upgrade_lock& other)BOOST_NOEXCEPT
909     {
910       std::swap(m,other.m);
911       std::swap(is_locked,other.is_locked);
912     }
mutex() const913     Mutex* mutex() const BOOST_NOEXCEPT
914     {
915       return m;
916     }
917 
release()918     Mutex* release()BOOST_NOEXCEPT
919     {
920       Mutex* const res=m;
921       m=0;
922       is_locked=false;
923       return res;
924     }
~upgrade_lock()925     ~upgrade_lock()
926     {
927       if (owns_lock())
928       {
929         m->unlock_upgrade();
930       }
931     }
lock()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 upgrade_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     }
try_lock()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 upgrade_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     }
unlock()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 upgrade_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>
try_lock_for(const chrono::duration<Rep,Period> & rel_time)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 upgrade_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 upgrade_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>
try_lock_until(const chrono::time_point<Clock,Duration> & abs_time)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 upgrade_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 upgrade_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)();
operator bool_type() const1009     operator bool_type() const BOOST_NOEXCEPT
1010     {
1011       return is_locked?&upgrade_lock::lock:0;
1012     }
operator !() const1013     bool operator!() const BOOST_NOEXCEPT
1014     {
1015       return !owns_lock();
1016     }
1017 #else
operator bool() const1018     explicit operator bool() const BOOST_NOEXCEPT
1019     {
1020       return owns_lock();
1021     }
1022 #endif
owns_lock() const1023     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>
swap(upgrade_lock<Mutex> & lhs,upgrade_lock<Mutex> & rhs)1032   void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs)
1033   BOOST_NOEXCEPT
1034   {
1035     lhs.swap(rhs);
1036   }
1037 
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex)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 
upgrade_to_unique_lock(upgrade_lock<Mutex> & m_)1062     explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) :
1063       source(&m_), exclusive(::boost::move(*source))
1064     {
1065     }
~upgrade_to_unique_lock()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 
upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)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
operator =(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)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(::boost::move(other));
1084       swap(temp);
1085       return *this;
1086     }
1087 
swap(upgrade_to_unique_lock & other)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&);
operator bool_type() const1096     operator bool_type() const BOOST_NOEXCEPT
1097     {
1098       return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
1099     }
operator !() const1100     bool operator!() const BOOST_NOEXCEPT
1101     {
1102       return !owns_lock();
1103     }
1104 #else
operator bool() const1105     explicit operator bool() const BOOST_NOEXCEPT
1106     {
1107       return owns_lock();
1108     }
1109 #endif
1110 
owns_lock() const1111     bool owns_lock() const BOOST_NOEXCEPT
1112     {
1113       return exclusive.owns_lock();
1114     }
mutex() const1115     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 
try_lock_wrapper()1133     try_lock_wrapper()
1134     {}
1135 
try_lock_wrapper(Mutex & m)1136     explicit try_lock_wrapper(Mutex& m):
1137     base(m,try_to_lock)
1138     {}
1139 
try_lock_wrapper(Mutex & m_,adopt_lock_t)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     }
try_lock_wrapper(Mutex & m_,defer_lock_t)1147     try_lock_wrapper(Mutex& m_,defer_lock_t):
1148     base(m_,defer_lock)
1149     {}
try_lock_wrapper(Mutex & m_,try_to_lock_t)1150     try_lock_wrapper(Mutex& m_,try_to_lock_t):
1151     base(m_,try_to_lock)
1152     {}
1153 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
try_lock_wrapper(BOOST_THREAD_RV_REF (try_lock_wrapper)other)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
try_lock_wrapper(BOOST_THREAD_RV_REF (try_lock_wrapper)other)1159     try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1160     base(::boost::move(static_cast<base&>(other)))
1161     {}
1162 
1163 #else
try_lock_wrapper(BOOST_THREAD_RV_REF (try_lock_wrapper)other)1164     try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1165     base(BOOST_THREAD_RV_REF(base)(*other))
1166     {}
1167 #endif
operator =(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)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(::boost::move(other));
1171       swap(temp);
1172       return *this;
1173     }
swap(try_lock_wrapper & other)1174     void swap(try_lock_wrapper& other)
1175     {
1176       base::swap(other);
1177     }
lock()1178     void lock()
1179     {
1180       base::lock();
1181     }
try_lock()1182     bool try_lock()
1183     {
1184       return base::try_lock();
1185     }
unlock()1186     void unlock()
1187     {
1188       base::unlock();
1189     }
owns_lock() const1190     bool owns_lock() const
1191     {
1192       return base::owns_lock();
1193     }
mutex() const1194     Mutex* mutex() const BOOST_NOEXCEPT
1195     {
1196       return base::mutex();
1197     }
release()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;
operator bool_type() const1205     operator bool_type() const
1206     {
1207       return base::operator bool_type();
1208     }
operator !() const1209     bool operator!() const
1210     {
1211       return !this->owns_lock();
1212     }
1213 #else
operator bool() const1214     explicit operator bool() const
1215     {
1216       return owns_lock();
1217     }
1218 #endif
1219   };
1220 
1221   template<typename Mutex>
swap(try_lock_wrapper<Mutex> & lhs,try_lock_wrapper<Mutex> & rhs)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