Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:31

0001 // Distributed under the Boost Software License, Version 1.0. (See
0002 // accompanying file LICENSE_1_0.txt or copy at
0003 // http://www.boost.org/LICENSE_1_0.txt)
0004 // (C) Copyright 2007 Anthony Williams
0005 // (C) Copyright 2011-2012 Vicente J. Botet Escriba
0006 
0007 #ifndef BOOST_THREAD_LOCK_TYPES_HPP
0008 #define BOOST_THREAD_LOCK_TYPES_HPP
0009 
0010 #include <boost/thread/detail/config.hpp>
0011 #include <boost/thread/detail/move.hpp>
0012 #include <boost/thread/exceptions.hpp>
0013 #include <boost/thread/lock_options.hpp>
0014 #include <boost/thread/lockable_traits.hpp>
0015 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
0016 #include <boost/thread/is_locked_by_this_thread.hpp>
0017 #endif
0018 #include <boost/thread/thread_time.hpp>
0019 
0020 #include <boost/assert.hpp>
0021 #ifdef BOOST_THREAD_USES_CHRONO
0022 #include <boost/chrono/time_point.hpp>
0023 #include <boost/chrono/duration.hpp>
0024 #endif
0025 #include <boost/detail/workaround.hpp>
0026 
0027 #include <boost/config/abi_prefix.hpp>
0028 
0029 namespace boost
0030 {
0031   struct xtime;
0032 
0033   template <typename Mutex>
0034   class shared_lock;
0035 
0036   template <typename Mutex>
0037   class upgrade_lock;
0038 
0039   template <typename Mutex>
0040   class unique_lock;
0041 
0042   namespace detail
0043   {
0044     template <typename Mutex>
0045     class try_lock_wrapper;
0046   }
0047 
0048 #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
0049   namespace sync
0050   {
0051     template<typename T>
0052     struct is_basic_lockable<unique_lock<T> >
0053     {
0054       BOOST_STATIC_CONSTANT(bool, value = true);
0055     };
0056     template<typename T>
0057     struct is_lockable<unique_lock<T> >
0058     {
0059       BOOST_STATIC_CONSTANT(bool, value = true);
0060     };
0061 
0062     template<typename T>
0063     struct is_basic_lockable<shared_lock<T> >
0064     {
0065       BOOST_STATIC_CONSTANT(bool, value = true);
0066     };
0067     template<typename T>
0068     struct is_lockable<shared_lock<T> >
0069     {
0070       BOOST_STATIC_CONSTANT(bool, value = true);
0071     };
0072 
0073     template<typename T>
0074     struct is_basic_lockable<upgrade_lock<T> >
0075     {
0076       BOOST_STATIC_CONSTANT(bool, value = true);
0077     };
0078     template<typename T>
0079     struct is_lockable<upgrade_lock<T> >
0080     {
0081       BOOST_STATIC_CONSTANT(bool, value = true);
0082     };
0083 
0084     template<typename T>
0085     struct is_basic_lockable<detail::try_lock_wrapper<T> >
0086     {
0087       BOOST_STATIC_CONSTANT(bool, value = true);
0088     };
0089     template<typename T>
0090     struct is_lockable<detail::try_lock_wrapper<T> >
0091     {
0092       BOOST_STATIC_CONSTANT(bool, value = true);
0093     };
0094   }
0095 #endif
0096 
0097 
0098   template <typename Mutex>
0099   class unique_lock
0100   {
0101   private:
0102     Mutex* m;
0103     bool is_locked;
0104 
0105   private:
0106     explicit unique_lock(upgrade_lock<Mutex>&);
0107     unique_lock& operator=(upgrade_lock<Mutex>& other);
0108   public:
0109     typedef Mutex mutex_type;
0110     BOOST_THREAD_MOVABLE_ONLY( unique_lock)
0111 
0112 #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
0113 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
0114     unique_lock(const volatile unique_lock&);
0115 #endif
0116 #endif
0117     unique_lock()BOOST_NOEXCEPT :
0118     m(0),is_locked(false)
0119     {}
0120 
0121     explicit unique_lock(Mutex& m_) :
0122       m(&m_), is_locked(false)
0123     {
0124       lock();
0125     }
0126     unique_lock(Mutex& m_, adopt_lock_t) :
0127       m(&m_), is_locked(true)
0128     {
0129 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
0130       BOOST_ASSERT(is_locked_by_this_thread(m));
0131 #endif
0132     }
0133     unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
0134     m(&m_),is_locked(false)
0135     {}
0136     unique_lock(Mutex& m_, try_to_lock_t) :
0137       m(&m_), is_locked(false)
0138     {
0139       try_lock();
0140     }
0141 #if defined BOOST_THREAD_USES_DATETIME
0142     template<typename TimeDuration>
0143     unique_lock(Mutex& m_,TimeDuration const& target_time):
0144     m(&m_),is_locked(false)
0145     {
0146       timed_lock(target_time);
0147     }
0148     unique_lock(Mutex& m_,system_time const& target_time):
0149     m(&m_),is_locked(false)
0150     {
0151       timed_lock(target_time);
0152     }
0153 #endif
0154 #ifdef BOOST_THREAD_USES_CHRONO
0155     template <class Clock, class Duration>
0156     unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
0157     : m(&mtx), is_locked(mtx.try_lock_until(t))
0158     {
0159     }
0160     template <class Rep, class Period>
0161     unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
0162     : m(&mtx), is_locked(mtx.try_lock_for(d))
0163     {
0164     }
0165 #endif
0166 
0167     unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT:
0168     m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
0169     {
0170       BOOST_THREAD_RV(other).is_locked=false;
0171       BOOST_THREAD_RV(other).m=0;
0172     }
0173 
0174     BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other);
0175 
0176 #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
0177     //std-2104 unique_lock move-assignment should not be noexcept
0178     unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
0179     {
0180       unique_lock temp(::boost::move(other));
0181       swap(temp);
0182       return *this;
0183     }
0184 #endif
0185 
0186     //std-2104 unique_lock move-assignment should not be noexcept
0187     unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT
0188     {
0189       unique_lock temp(::boost::move(other));
0190       swap(temp);
0191       return *this;
0192     }
0193 #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
0194 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
0195     unique_lock& operator=(unique_lock<Mutex> other)
0196     {
0197       swap(other);
0198       return *this;
0199     }
0200 #endif // BOOST_WORKAROUND
0201 #endif
0202 
0203     // Conversion from upgrade locking
0204     unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t)
0205     : m(0),is_locked(false)
0206     {
0207       if (BOOST_THREAD_RV(ul).owns_lock())
0208       {
0209         if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock())
0210         {
0211           m = BOOST_THREAD_RV(ul).release();
0212           is_locked = true;
0213         }
0214       }
0215       else
0216       {
0217         m = BOOST_THREAD_RV(ul).release();
0218       }
0219     }
0220 
0221 #ifdef BOOST_THREAD_USES_CHRONO
0222     template <class Clock, class Duration>
0223     unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
0224         const chrono::time_point<Clock, Duration>& abs_time)
0225     : m(0),is_locked(false)
0226     {
0227       if (BOOST_THREAD_RV(ul).owns_lock())
0228       {
0229         if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time))
0230         {
0231           m = BOOST_THREAD_RV(ul).release();
0232           is_locked = true;
0233         }
0234       }
0235       else
0236       {
0237         m = BOOST_THREAD_RV(ul).release();
0238       }
0239     }
0240 
0241     template <class Rep, class Period>
0242     unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
0243         const chrono::duration<Rep, Period>& rel_time)
0244     : m(0),is_locked(false)
0245     {
0246       if (BOOST_THREAD_RV(ul).owns_lock())
0247       {
0248         if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time))
0249         {
0250           m = BOOST_THREAD_RV(ul).release();
0251           is_locked = true;
0252         }
0253       }
0254       else
0255       {
0256         m = BOOST_THREAD_RV(ul).release();
0257       }
0258     }
0259 #endif
0260 
0261 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
0262     // Conversion from shared locking
0263     unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
0264     : m(0),is_locked(false)
0265     {
0266       if (BOOST_THREAD_RV(sl).owns_lock())
0267       {
0268         if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock())
0269         {
0270           m = BOOST_THREAD_RV(sl).release();
0271           is_locked = true;
0272         }
0273       }
0274       else
0275       {
0276         m = BOOST_THREAD_RV(sl).release();
0277       }
0278     }
0279 
0280 #ifdef BOOST_THREAD_USES_CHRONO
0281     template <class Clock, class Duration>
0282     unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
0283         const chrono::time_point<Clock, Duration>& abs_time)
0284     : m(0),is_locked(false)
0285     {
0286       if (BOOST_THREAD_RV(sl).owns_lock())
0287       {
0288         if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time))
0289         {
0290           m = BOOST_THREAD_RV(sl).release();
0291           is_locked = true;
0292         }
0293       }
0294       else
0295       {
0296         m = BOOST_THREAD_RV(sl).release();
0297       }
0298     }
0299 
0300     template <class Rep, class Period>
0301     unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
0302         const chrono::duration<Rep, Period>& rel_time)
0303     : m(0),is_locked(false)
0304     {
0305       if (BOOST_THREAD_RV(sl).owns_lock())
0306       {
0307         if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time))
0308         {
0309           m = BOOST_THREAD_RV(sl).release();
0310           is_locked = true;
0311         }
0312       }
0313       else
0314       {
0315         m = BOOST_THREAD_RV(sl).release();
0316       }
0317     }
0318 #endif // BOOST_THREAD_USES_CHRONO
0319 #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
0320 
0321     void swap(unique_lock& other)BOOST_NOEXCEPT
0322     {
0323       std::swap(m,other.m);
0324       std::swap(is_locked,other.is_locked);
0325     }
0326 
0327     ~unique_lock()
0328     {
0329       if (owns_lock())
0330       {
0331         m->unlock();
0332       }
0333     }
0334     void lock()
0335     {
0336       if (m == 0)
0337       {
0338         boost::throw_exception(
0339             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0340       }
0341       if (owns_lock())
0342       {
0343         boost::throw_exception(
0344             boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0345       }
0346       m->lock();
0347       is_locked = true;
0348     }
0349     bool try_lock()
0350     {
0351       if (m == 0)
0352       {
0353         boost::throw_exception(
0354             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0355       }
0356       if (owns_lock())
0357       {
0358         boost::throw_exception(
0359             boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0360       }
0361       is_locked = m->try_lock();
0362       return is_locked;
0363     }
0364 #if defined BOOST_THREAD_USES_DATETIME
0365     template<typename TimeDuration>
0366     bool timed_lock(TimeDuration const& relative_time)
0367     {
0368       if(m==0)
0369       {
0370         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0371       }
0372       if(owns_lock())
0373       {
0374         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0375       }
0376       is_locked=m->timed_lock(relative_time);
0377       return is_locked;
0378     }
0379 
0380     bool timed_lock(::boost::system_time const& absolute_time)
0381     {
0382       if(m==0)
0383       {
0384         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0385       }
0386       if(owns_lock())
0387       {
0388         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0389       }
0390       is_locked=m->timed_lock(absolute_time);
0391       return is_locked;
0392     }
0393     bool timed_lock(::boost::xtime const& absolute_time)
0394     {
0395       if(m==0)
0396       {
0397         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0398       }
0399       if(owns_lock())
0400       {
0401         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0402       }
0403       is_locked=m->timed_lock(absolute_time);
0404       return is_locked;
0405     }
0406 #endif
0407 #ifdef BOOST_THREAD_USES_CHRONO
0408 
0409     template <class Rep, class Period>
0410     bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
0411     {
0412       if(m==0)
0413       {
0414         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0415       }
0416       if(owns_lock())
0417       {
0418         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0419       }
0420       is_locked=m->try_lock_for(rel_time);
0421       return is_locked;
0422     }
0423     template <class Clock, class Duration>
0424     bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
0425     {
0426       if(m==0)
0427       {
0428         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0429       }
0430       if(owns_lock())
0431       {
0432         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
0433       }
0434       is_locked=m->try_lock_until(abs_time);
0435       return is_locked;
0436     }
0437 #endif
0438 
0439     void unlock()
0440     {
0441       if (m == 0)
0442       {
0443         boost::throw_exception(
0444             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
0445       }
0446       if (!owns_lock())
0447       {
0448         boost::throw_exception(
0449             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock doesn't own the mutex"));
0450       }
0451       m->unlock();
0452       is_locked = false;
0453     }
0454 
0455 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
0456     typedef void (unique_lock::*bool_type)();
0457     operator bool_type() const BOOST_NOEXCEPT
0458     {
0459       return is_locked?&unique_lock::lock:0;
0460     }
0461     bool operator!() const BOOST_NOEXCEPT
0462     {
0463       return !owns_lock();
0464     }
0465 #else
0466     explicit operator bool() const BOOST_NOEXCEPT
0467     {
0468       return owns_lock();
0469     }
0470 #endif
0471     bool owns_lock() const BOOST_NOEXCEPT
0472     {
0473       return is_locked;
0474     }
0475 
0476     Mutex* mutex() const BOOST_NOEXCEPT
0477     {
0478       return m;
0479     }
0480 
0481     Mutex* release()BOOST_NOEXCEPT
0482     {
0483       Mutex* const res=m;
0484       m=0;
0485       is_locked=false;
0486       return res;
0487     }
0488 
0489     friend class shared_lock<Mutex> ;
0490     friend class upgrade_lock<Mutex> ;
0491   };
0492 
0493   template<typename Mutex>
0494   void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs)
0495   BOOST_NOEXCEPT
0496   {
0497     lhs.swap(rhs);
0498   }
0499 
0500   BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
0501 
0502   template<typename Mutex>
0503   class shared_lock
0504   {
0505   protected:
0506     Mutex* m;
0507     bool is_locked;
0508 
0509   public:
0510     typedef Mutex mutex_type;
0511     BOOST_THREAD_MOVABLE_ONLY(shared_lock)
0512 
0513     shared_lock() BOOST_NOEXCEPT:
0514     m(0),is_locked(false)
0515     {}
0516 
0517     explicit shared_lock(Mutex& m_):
0518     m(&m_),is_locked(false)
0519     {
0520       lock();
0521     }
0522     shared_lock(Mutex& m_,adopt_lock_t):
0523     m(&m_),is_locked(true)
0524     {
0525 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
0526       BOOST_ASSERT(is_locked_by_this_thread(m));
0527 #endif
0528     }
0529     shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
0530     m(&m_),is_locked(false)
0531     {}
0532     shared_lock(Mutex& m_,try_to_lock_t):
0533     m(&m_),is_locked(false)
0534     {
0535       try_lock();
0536     }
0537 #if defined BOOST_THREAD_USES_DATETIME
0538     shared_lock(Mutex& m_,system_time const& target_time):
0539     m(&m_),is_locked(false)
0540     {
0541       timed_lock(target_time);
0542     }
0543 #endif
0544 #ifdef BOOST_THREAD_USES_CHRONO
0545     template <class Clock, class Duration>
0546     shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
0547     : m(&mtx), is_locked(mtx.try_lock_shared_until(t))
0548     {
0549     }
0550     template <class Rep, class Period>
0551     shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
0552     : m(&mtx), is_locked(mtx.try_lock_shared_for(d))
0553     {
0554     }
0555 #endif
0556 
0557     shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
0558     m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
0559     {
0560       BOOST_THREAD_RV(other).is_locked=false;
0561       BOOST_THREAD_RV(other).m=0;
0562     }
0563 
0564     BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
0565     m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
0566     {
0567       if(is_locked)
0568       {
0569         m->unlock_and_lock_shared();
0570       }
0571       BOOST_THREAD_RV(other).is_locked=false;
0572       BOOST_THREAD_RV(other).m=0;
0573     }
0574 
0575     BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
0576     m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
0577     {
0578       if(is_locked)
0579       {
0580         m->unlock_upgrade_and_lock_shared();
0581       }
0582       BOOST_THREAD_RV(other).is_locked=false;
0583       BOOST_THREAD_RV(other).m=0;
0584     }
0585 
0586     //std-2104 unique_lock move-assignment should not be noexcept
0587     shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
0588     {
0589       shared_lock temp(::boost::move(other));
0590       swap(temp);
0591       return *this;
0592     }
0593 #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
0594     shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
0595     {
0596       shared_lock temp(::boost::move(other));
0597       swap(temp);
0598       return *this;
0599     }
0600 
0601     shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)
0602     {
0603       shared_lock temp(::boost::move(other));
0604       swap(temp);
0605       return *this;
0606     }
0607 #endif
0608 
0609     void swap(shared_lock& other) BOOST_NOEXCEPT
0610     {
0611       std::swap(m,other.m);
0612       std::swap(is_locked,other.is_locked);
0613     }
0614 
0615     Mutex* mutex() const BOOST_NOEXCEPT
0616     {
0617       return m;
0618     }
0619 
0620     Mutex* release() BOOST_NOEXCEPT
0621     {
0622       Mutex* const res=m;
0623       m=0;
0624       is_locked=false;
0625       return res;
0626     }
0627 
0628     ~shared_lock()
0629     {
0630       if(owns_lock())
0631       {
0632         m->unlock_shared();
0633       }
0634     }
0635     void lock()
0636     {
0637       if(m==0)
0638       {
0639         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0640       }
0641       if(owns_lock())
0642       {
0643         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
0644       }
0645       m->lock_shared();
0646       is_locked=true;
0647     }
0648     bool try_lock()
0649     {
0650       if(m==0)
0651       {
0652         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0653       }
0654       if(owns_lock())
0655       {
0656         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
0657       }
0658       is_locked=m->try_lock_shared();
0659       return is_locked;
0660     }
0661 #if defined BOOST_THREAD_USES_DATETIME
0662     bool timed_lock(boost::system_time const& target_time)
0663     {
0664       if(m==0)
0665       {
0666         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0667       }
0668       if(owns_lock())
0669       {
0670         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
0671       }
0672       is_locked=m->timed_lock_shared(target_time);
0673       return is_locked;
0674     }
0675     template<typename Duration>
0676     bool timed_lock(Duration const& target_time)
0677     {
0678       if(m==0)
0679       {
0680         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0681       }
0682       if(owns_lock())
0683       {
0684         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
0685       }
0686       is_locked=m->timed_lock_shared(target_time);
0687       return is_locked;
0688     }
0689 #endif
0690 #ifdef BOOST_THREAD_USES_CHRONO
0691     template <class Rep, class Period>
0692     bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
0693     {
0694       if(m==0)
0695       {
0696         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0697       }
0698       if(owns_lock())
0699       {
0700         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
0701       }
0702       is_locked=m->try_lock_shared_for(rel_time);
0703       return is_locked;
0704     }
0705     template <class Clock, class Duration>
0706     bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
0707     {
0708       if(m==0)
0709       {
0710         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0711       }
0712       if(owns_lock())
0713       {
0714         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
0715       }
0716       is_locked=m->try_lock_shared_until(abs_time);
0717       return is_locked;
0718     }
0719 #endif
0720     void unlock()
0721     {
0722       if(m==0)
0723       {
0724         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
0725       }
0726       if(!owns_lock())
0727       {
0728         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock doesn't own the mutex"));
0729       }
0730       m->unlock_shared();
0731       is_locked=false;
0732     }
0733 
0734 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
0735     typedef void (shared_lock<Mutex>::*bool_type)();
0736     operator bool_type() const BOOST_NOEXCEPT
0737     {
0738       return is_locked?&shared_lock::lock:0;
0739     }
0740     bool operator!() const BOOST_NOEXCEPT
0741     {
0742       return !owns_lock();
0743     }
0744 #else
0745     explicit operator bool() const BOOST_NOEXCEPT
0746     {
0747       return owns_lock();
0748     }
0749 #endif
0750     bool owns_lock() const BOOST_NOEXCEPT
0751     {
0752       return is_locked;
0753     }
0754 
0755   };
0756 
0757   BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
0758 
0759   template<typename Mutex>
0760   void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
0761   {
0762     lhs.swap(rhs);
0763   }
0764 
0765   template <typename Mutex>
0766   class upgrade_lock
0767   {
0768   protected:
0769     Mutex* m;
0770     bool is_locked;
0771 
0772   public:
0773     typedef Mutex mutex_type;
0774     BOOST_THREAD_MOVABLE_ONLY( upgrade_lock)
0775 
0776     upgrade_lock()BOOST_NOEXCEPT:
0777     m(0),is_locked(false)
0778     {}
0779 
0780     explicit upgrade_lock(Mutex& m_) :
0781       m(&m_), is_locked(false)
0782     {
0783       lock();
0784     }
0785     upgrade_lock(Mutex& m_, adopt_lock_t) :
0786       m(&m_), is_locked(true)
0787     {
0788 #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
0789       BOOST_ASSERT(is_locked_by_this_thread(m));
0790 #endif
0791     }
0792     upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
0793     m(&m_),is_locked(false)
0794     {}
0795     upgrade_lock(Mutex& m_, try_to_lock_t) :
0796       m(&m_), is_locked(false)
0797     {
0798       try_lock();
0799     }
0800 
0801 #ifdef BOOST_THREAD_USES_CHRONO
0802     template <class Clock, class Duration>
0803     upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
0804     : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t))
0805     {
0806     }
0807     template <class Rep, class Period>
0808     upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
0809     : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d))
0810     {
0811     }
0812 #endif
0813 
0814     upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
0815     m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
0816     {
0817       BOOST_THREAD_RV(other).is_locked=false;
0818       BOOST_THREAD_RV(other).m=0;
0819     }
0820 
0821     BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
0822     m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
0823     {
0824       if(is_locked)
0825       {
0826         m->unlock_and_lock_upgrade();
0827       }
0828       BOOST_THREAD_RV(other).is_locked=false;
0829       BOOST_THREAD_RV(other).m=0;
0830     }
0831 
0832     //std-2104 unique_lock move-assignment should not be noexcept
0833     upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
0834     {
0835       upgrade_lock temp(::boost::move(other));
0836       swap(temp);
0837       return *this;
0838     }
0839 
0840 #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
0841     upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
0842     {
0843       upgrade_lock temp(::boost::move(other));
0844       swap(temp);
0845       return *this;
0846     }
0847 #endif
0848 
0849 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
0850     // Conversion from shared locking
0851     upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
0852     : m(0),is_locked(false)
0853     {
0854       if (BOOST_THREAD_RV(sl).owns_lock())
0855       {
0856         if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())
0857         {
0858           m = BOOST_THREAD_RV(sl).release();
0859           is_locked = true;
0860         }
0861       }
0862       else
0863       {
0864         m = BOOST_THREAD_RV(sl).release();
0865       }
0866     }
0867 
0868 #ifdef BOOST_THREAD_USES_CHRONO
0869     template <class Clock, class Duration>
0870     upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
0871         const chrono::time_point<Clock, Duration>& abs_time)
0872     : m(0),is_locked(false)
0873     {
0874       if (BOOST_THREAD_RV(sl).owns_lock())
0875       {
0876         if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
0877         {
0878           m = BOOST_THREAD_RV(sl).release();
0879           is_locked = true;
0880         }
0881       }
0882       else
0883       {
0884         m = BOOST_THREAD_RV(sl).release();
0885       }
0886     }
0887 
0888     template <class Rep, class Period>
0889     upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
0890         const chrono::duration<Rep, Period>& rel_time)
0891     : m(0),is_locked(false)
0892     {
0893       if (BOOST_THREAD_RV(sl).owns_lock())
0894       {
0895         if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
0896         {
0897           m = BOOST_THREAD_RV(sl).release();
0898           is_locked = true;
0899         }
0900       }
0901       else
0902       {
0903         m = BOOST_THREAD_RV(sl).release();
0904       }
0905     }
0906 #endif // BOOST_THREAD_USES_CHRONO
0907 #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
0908     void swap(upgrade_lock& other)BOOST_NOEXCEPT
0909     {
0910       std::swap(m,other.m);
0911       std::swap(is_locked,other.is_locked);
0912     }
0913     Mutex* mutex() const BOOST_NOEXCEPT
0914     {
0915       return m;
0916     }
0917 
0918     Mutex* release()BOOST_NOEXCEPT
0919     {
0920       Mutex* const res=m;
0921       m=0;
0922       is_locked=false;
0923       return res;
0924     }
0925     ~upgrade_lock()
0926     {
0927       if (owns_lock())
0928       {
0929         m->unlock_upgrade();
0930       }
0931     }
0932     void lock()
0933     {
0934       if (m == 0)
0935       {
0936         boost::throw_exception(
0937             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
0938       }
0939       if (owns_lock())
0940       {
0941         boost::throw_exception(
0942             boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
0943       }
0944       m->lock_upgrade();
0945       is_locked = true;
0946     }
0947     bool try_lock()
0948     {
0949       if (m == 0)
0950       {
0951         boost::throw_exception(
0952             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
0953       }
0954       if (owns_lock())
0955       {
0956         boost::throw_exception(
0957             boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
0958       }
0959       is_locked = m->try_lock_upgrade();
0960       return is_locked;
0961     }
0962     void unlock()
0963     {
0964       if (m == 0)
0965       {
0966         boost::throw_exception(
0967             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
0968       }
0969       if (!owns_lock())
0970       {
0971         boost::throw_exception(
0972             boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock doesn't own the mutex"));
0973       }
0974       m->unlock_upgrade();
0975       is_locked = false;
0976     }
0977 #ifdef BOOST_THREAD_USES_CHRONO
0978     template <class Rep, class Period>
0979     bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
0980     {
0981       if(m==0)
0982       {
0983         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
0984       }
0985       if(owns_lock())
0986       {
0987         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
0988       }
0989       is_locked=m->try_lock_upgrade_for(rel_time);
0990       return is_locked;
0991     }
0992     template <class Clock, class Duration>
0993     bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
0994     {
0995       if(m==0)
0996       {
0997         boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
0998       }
0999       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)();
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(::boost::move(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(::boost::move(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