Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:32:42

0001 // (C) Copyright 2012 Vicente J. Botet Escriba
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 
0007 #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_HPP
0008 #define BOOST_THREAD_EXTERNALLY_LOCKED_HPP
0009 
0010 #include <boost/thread/detail/config.hpp>
0011 
0012 #include <boost/thread/exceptions.hpp>
0013 #include <boost/thread/lock_concepts.hpp>
0014 #include <boost/thread/lock_traits.hpp>
0015 #include <boost/thread/lockable_concepts.hpp>
0016 #include <boost/thread/strict_lock.hpp>
0017 
0018 #include <boost/static_assert.hpp>
0019 #include <boost/type_traits/is_same.hpp>
0020 #include <boost/throw_exception.hpp>
0021 #include <boost/core/invoke_swap.hpp>
0022 
0023 #include <boost/config/abi_prefix.hpp>
0024 
0025 namespace boost
0026 {
0027   class mutex;
0028 
0029   /**
0030    * externally_locked cloaks an object of type T, and actually provides full
0031    * access to that object through the get and set member functions, provided you
0032    * pass a reference to a strict lock object
0033    */
0034 
0035   //[externally_locked
0036   template <typename T, typename MutexType = boost::mutex>
0037   class externally_locked;
0038   template <typename T, typename MutexType>
0039   class externally_locked
0040   {
0041     //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
0042     BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
0043 
0044   public:
0045     typedef MutexType mutex_type;
0046 
0047     BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
0048     /**
0049      * Requires: T is a model of CopyConstructible.
0050      * Effects: Constructs an externally locked object copying the cloaked type.
0051      */
0052     externally_locked(mutex_type& mtx, const T& obj) :
0053       obj_(obj), mtx_(&mtx)
0054     {
0055     }
0056 
0057     /**
0058      * Requires: T is a model of Movable.
0059      * Effects: Constructs an externally locked object by moving the cloaked type.
0060      */
0061     externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
0062       obj_(move(obj)), mtx_(&mtx)
0063     {
0064     }
0065 
0066     /**
0067      * Requires: T is a model of DefaultConstructible.
0068      * Effects: Constructs an externally locked object initializing the cloaked type with the default constructor.
0069      */
0070     externally_locked(mutex_type& mtx) // BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T()))
0071     : obj_(), mtx_(&mtx)
0072     {
0073     }
0074 
0075     /**
0076      *  Copy constructor
0077      */
0078     externally_locked(externally_locked const& rhs) //BOOST_NOEXCEPT
0079     : obj_(rhs.obj_), mtx_(rhs.mtx_)
0080     {
0081     }
0082     /**
0083      *  Move constructor
0084      */
0085     externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) //BOOST_NOEXCEPT
0086     : obj_(move(rhs.obj_)), mtx_(rhs.mtx_)
0087     {
0088     }
0089 
0090     /// assignment
0091     externally_locked& operator=(externally_locked const& rhs) //BOOST_NOEXCEPT
0092     {
0093       obj_=rhs.obj_;
0094       mtx_=rhs.mtx_;
0095       return *this;
0096     }
0097 
0098     /// move assignment
0099     externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) // BOOST_NOEXCEPT
0100     {
0101       obj_=move(BOOST_THREAD_RV(rhs).obj_);
0102       mtx_=rhs.mtx_;
0103       return *this;
0104     }
0105 
0106     void swap(externally_locked& rhs) //BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR)
0107     {
0108       boost::core::invoke_swap(obj_, rhs.obj_);
0109       boost::core::invoke_swap(mtx_, rhs.mtx_);
0110     }
0111 
0112     /**
0113      * Requires: The lk parameter must be locking the associated mtx.
0114      *
0115      * Returns: The address of the cloaked object..
0116      *
0117      * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
0118      */
0119     T& get(strict_lock<mutex_type>& lk)
0120     {
0121       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0122       return obj_;
0123     }
0124 
0125     const T& get(strict_lock<mutex_type>& lk) const
0126     {
0127       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0128       return obj_;
0129     }
0130 
0131     template <class Lock>
0132     T& get(nested_strict_lock<Lock>& lk)
0133     {
0134       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0135       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0136       return obj_;
0137     }
0138 
0139     template <class Lock>
0140     const T& get(nested_strict_lock<Lock>& lk) const
0141     {
0142       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0143       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0144       return obj_;
0145     }
0146 
0147     /**
0148      * Requires: The lk parameter must be locking the associated mtx.
0149      * Returns: The address of the cloaked object..
0150      *
0151      * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
0152      */
0153     template <class Lock>
0154     T& get(Lock& lk)
0155     {
0156       BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
0157       BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
0158       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0159 
0160       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0161 
0162       return obj_;
0163     }
0164 
0165     mutex_type* mutex() const BOOST_NOEXCEPT
0166     {
0167       return mtx_;
0168     }
0169 
0170     // modifiers
0171 
0172     void lock()
0173     {
0174       mtx_->lock();
0175     }
0176     void unlock()
0177     {
0178       mtx_->unlock();
0179     }
0180     bool try_lock()
0181     {
0182       return mtx_->try_lock();
0183     }
0184     // todo add time related functions
0185 
0186   private:
0187     T obj_;
0188     mutex_type* mtx_;
0189   };
0190   //]
0191 
0192   /**
0193    * externally_locked<T&,M> specialization for T& that cloaks an reference to an object of type T, and actually
0194    * provides full access to that object through the get and set member functions, provided you
0195    * pass a reference to a strict lock object.
0196    */
0197 
0198   //[externally_locked_ref
0199   template <typename T, typename MutexType>
0200   class externally_locked<T&, MutexType>
0201   {
0202     //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
0203     BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
0204 
0205   public:
0206     typedef MutexType mutex_type;
0207 
0208     BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
0209 
0210     /**
0211      * Effects: Constructs an externally locked object storing the cloaked reference object.
0212      */
0213     externally_locked(T& obj, mutex_type& mtx) BOOST_NOEXCEPT :
0214       obj_(&obj), mtx_(&mtx)
0215     {
0216     }
0217 
0218     /// copy constructor
0219     externally_locked(externally_locked const& rhs) BOOST_NOEXCEPT :
0220     obj_(rhs.obj_), mtx_(rhs.mtx_)
0221     {
0222     }
0223 
0224     /// move constructor
0225     externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT :
0226     obj_(rhs.obj_), mtx_(rhs.mtx_)
0227     {
0228     }
0229 
0230     /// assignment
0231     externally_locked& operator=(externally_locked const& rhs) BOOST_NOEXCEPT
0232     {
0233       obj_=rhs.obj_;
0234       mtx_=rhs.mtx_;
0235       return *this;
0236     }
0237 
0238     /// move assignment
0239     externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT
0240     {
0241       obj_=rhs.obj_;
0242       mtx_=rhs.mtx_;
0243       return *this;
0244     }
0245 
0246     void swap(externally_locked& rhs) BOOST_NOEXCEPT
0247     {
0248       boost::core::invoke_swap(obj_, rhs.obj_);
0249       boost::core::invoke_swap(mtx_, rhs.mtx_);
0250     }
0251     /**
0252      * Requires: The lk parameter must be locking the associated mtx.
0253      *
0254      * Returns: The address of the cloaked object..
0255      *
0256      * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
0257      */
0258     T& get(strict_lock<mutex_type> const& lk)
0259     {
0260       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0261       return *obj_;
0262     }
0263 
0264     const T& get(strict_lock<mutex_type> const& lk) const
0265     {
0266       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0267       return *obj_;
0268     }
0269 
0270     template <class Lock>
0271     T& get(nested_strict_lock<Lock> const& lk)
0272     {
0273       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0274       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0275       return *obj_;
0276     }
0277 
0278     template <class Lock>
0279     const T& get(nested_strict_lock<Lock> const& lk) const
0280     {
0281       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0282       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0283       return *obj_;
0284     }
0285 
0286     /**
0287      * Requires: The lk parameter must be locking the associated mtx.
0288      * Returns: The address of the cloaked object..
0289      *
0290      * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
0291      */
0292     template <class Lock>
0293     T& get(Lock const& lk)
0294     {
0295       BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
0296       BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
0297       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0298       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0299       return *obj_;
0300     }
0301 
0302     /**
0303      * Requires: The lk parameter must be locking the associated mtx.
0304      * Returns: The address of the cloaked object..
0305      *
0306      * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
0307      */
0308     template <class Lock>
0309     T const& get(Lock const& lk) const
0310     {
0311       BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
0312       BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
0313       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
0314       BOOST_THREAD_ASSERT_PRECONDITION(  lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
0315       return *obj_;
0316     }
0317     mutex_type* mutex() const BOOST_NOEXCEPT
0318     {
0319       return mtx_;
0320     }
0321 
0322     void lock()
0323     {
0324       mtx_->lock();
0325     }
0326     void unlock()
0327     {
0328       mtx_->unlock();
0329     }
0330     bool try_lock()
0331     {
0332       return mtx_->try_lock();
0333     }
0334     // todo add time related functions
0335 
0336   protected:
0337     T* obj_;
0338     mutex_type* mtx_;
0339   };
0340   //]
0341 
0342   template <typename T, typename MutexType>
0343   void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs) // BOOST_NOEXCEPT
0344   {
0345     lhs.swap(rhs);
0346   }
0347 
0348 }
0349 
0350 #include <boost/config/abi_suffix.hpp>
0351 
0352 #endif // header