Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/thread/strict_lock.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 2008-2009,2012 Vicente J. Botet Escriba
0005 
0006 #ifndef BOOST_THREAD_STRICT_LOCK_HPP
0007 #define BOOST_THREAD_STRICT_LOCK_HPP
0008 
0009 #include <boost/thread/detail/config.hpp>
0010 #include <boost/thread/detail/delete.hpp>
0011 #include <boost/thread/detail/lockable_wrapper.hpp>
0012 #include <boost/thread/lock_options.hpp>
0013 #include <boost/thread/lock_traits.hpp>
0014 #include <boost/thread/lockable_traits.hpp>
0015 #include <boost/thread/lockable_concepts.hpp>
0016 #include <boost/thread/lock_concepts.hpp>
0017 #include <boost/thread/exceptions.hpp>
0018 #include <boost/throw_exception.hpp>
0019 
0020 #include <boost/config/abi_prefix.hpp>
0021 
0022 namespace boost
0023 {
0024 
0025 
0026   //[strict_lock
0027   template <typename Lockable>
0028   class strict_lock
0029   {
0030 
0031     BOOST_CONCEPT_ASSERT(( BasicLockable<Lockable> ));
0032   public:
0033     typedef Lockable mutex_type;
0034 
0035     // construct/copy/destroy:
0036 
0037     BOOST_THREAD_NO_COPYABLE( strict_lock)
0038 
0039     /**
0040      * Constructor from a mutex reference.
0041      *
0042      * @param mtx the mutex to lock.
0043      *
0044      * __Effects: Stores a reference to the mutex to lock and locks it.
0045      * __Throws: Any exception BasicMutex::lock() can throw.
0046      */
0047     explicit strict_lock(mutex_type& mtx) :
0048       mtx_(mtx)
0049     {
0050       mtx.lock();
0051     } /*< locks on construction >*/
0052 
0053 
0054 #if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
0055     strict_lock(std::initializer_list<thread_detail::lockable_wrapper<Lockable> > l_) :
0056       mtx_(*(const_cast<thread_detail::lockable_wrapper<Lockable>*>(l_.begin())->m))
0057     {
0058       mtx_.lock();
0059     }
0060 #endif
0061 
0062     /**
0063      * Destructor
0064      *
0065      * __Effects: unlocks the stored mutex.
0066      *
0067      * __Throws
0068      */
0069     ~strict_lock()
0070     {
0071       mtx_.unlock();
0072     } /*< unlocks on destruction >*/
0073 
0074 
0075     // observers
0076 
0077     /**
0078      * @return the owned mutex.
0079      */
0080     mutex_type* mutex() const BOOST_NOEXCEPT
0081     {
0082       return &mtx_;
0083     }
0084 
0085     /**
0086      * @return whether this lock is locking a mutex.
0087      */
0088     bool owns_lock() const BOOST_NOEXCEPT
0089     {
0090       return true;
0091     }
0092 
0093     /**
0094      * @return whether this lock is locking that mutex.
0095      */
0096     bool owns_lock(const mutex_type* l) const BOOST_NOEXCEPT
0097     {
0098       return l == mutex();
0099     } /*< strict locks specific function >*/
0100 
0101     //BOOST_ADRESS_OF_DELETE(strict_lock) /*< disable aliasing >*/
0102     //BOOST_HEAP_ALLOCATION_DELETE(strict_lock) /*< disable heap allocation >*/
0103 
0104     /*< no possibility to unlock >*/
0105 
0106   private:
0107     mutex_type& mtx_;
0108   };
0109   //]
0110   template <typename Lockable>
0111   struct is_strict_lock_sur_parole<strict_lock<Lockable> > : true_type
0112   {
0113   };
0114 
0115   /**
0116    * A nested strict lock is a scoped lock guard ensuring the mutex is locked on its
0117    * scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked
0118    * and restoring the ownership to the nesting lock on destruction.
0119    */
0120   //[nested_strict_lock
0121   template <typename Lock>
0122   class nested_strict_lock
0123   {
0124     BOOST_CONCEPT_ASSERT(( BasicLock<Lock> )); /*< The Lock must be a movable lock >*/
0125   public:
0126     typedef typename Lock::mutex_type mutex_type; /*< Name the lockable type locked by Lock >*/
0127 
0128     BOOST_THREAD_NO_COPYABLE( nested_strict_lock)
0129 
0130     /**
0131      * Constructor from a nesting @c Lock.
0132      *
0133      * @param lk the nesting lock
0134      *
0135      * __Requires: <c>lk.mutex() != null_ptr</c>
0136      * __Effects: Stores the reference to the lock parameter and takes ownership on it.
0137      * If the lock doesn't owns the mutex @c mtx lock it.
0138      * __Postconditions: @c owns_lock(lk.mutex())
0139      * __StrongException
0140      * __Throws:
0141      *
0142      * - lock_error when BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and lk.mutex() == null_ptr
0143      *
0144      * - Any exception that @c lk.lock() can throw.
0145      *
0146      */
0147     explicit nested_strict_lock(Lock& lk) :
0148       lk_(lk) /*< Store reference to lk >*/
0149     {
0150       /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/
0151       BOOST_THREAD_ASSERT_PRECONDITION(  lk.mutex() != 0,
0152           lock_error()
0153       );
0154       if (!lk.owns_lock()) lk.lock(); /*< ensures it is locked >*/
0155       tmp_lk_ = move(lk); /*< Move ownership to temporary lk >*/
0156     }
0157 
0158 #if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
0159     nested_strict_lock(std::initializer_list<thread_detail::lockable_wrapper<Lock> > l_) :
0160       lk_(*(const_cast<thread_detail::lockable_wrapper<Lock>*>(l_.begin())->m))
0161     {
0162       /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/
0163       BOOST_THREAD_ASSERT_PRECONDITION(  lk_.mutex() != 0,
0164           lock_error()
0165       );
0166       if (!lk_.owns_lock()) lk_.lock(); /*< ensures it is locked >*/
0167       tmp_lk_ = move(lk_); /*< Move ownership to temporary lk >*/
0168     }
0169 #endif
0170 
0171     /**
0172      * Destructor
0173      *
0174      * __Effects: Restores ownership to the nesting lock.
0175      */
0176     ~nested_strict_lock()BOOST_NOEXCEPT
0177     {
0178       lk_ = move(tmp_lk_); /*< Move ownership to nesting lock >*/
0179     }
0180 
0181     // observers
0182     /**
0183      * return @c the owned mutex.
0184      */
0185     mutex_type* mutex() const BOOST_NOEXCEPT
0186     {
0187       return tmp_lk_.mutex();
0188     }
0189 
0190     /**
0191      * @return whether this lock is locking a mutex.
0192      */
0193     bool owns_lock() const BOOST_NOEXCEPT
0194     {
0195       return true;
0196     }
0197 
0198     /**
0199      * @return whether if this lock is locking that mutex.
0200      */
0201     bool owns_lock(mutex_type const* l) const BOOST_NOEXCEPT
0202     {
0203       return l == mutex();
0204     }
0205 
0206     //BOOST_ADRESS_OF_DELETE(nested_strict_lock)
0207     //BOOST_HEAP_ALLOCATEION_DELETE(nested_strict_lock)
0208 
0209   private:
0210     Lock& lk_;
0211     Lock tmp_lk_;
0212   };
0213   //]
0214 
0215   template <typename Lock>
0216   struct is_strict_lock_sur_parole<nested_strict_lock<Lock> > : true_type
0217   {
0218   };
0219 
0220 #if ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK
0221   template <typename Lockable>
0222   strict_lock<Lockable> make_strict_lock(Lockable& mtx)
0223   {
0224     return { thread_detail::lockable_wrapper<Lockable>(mtx) };
0225   }
0226   template <typename Lock>
0227   nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk)
0228   {
0229     return { thread_detail::lockable_wrapper<Lock>(lk) };
0230   }
0231 #endif
0232 }
0233 #include <boost/config/abi_suffix.hpp>
0234 
0235 #endif