123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- // (C) Copyright 2012 Vicente J. Botet Escriba
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_HPP
- #define BOOST_THREAD_EXTERNALLY_LOCKED_HPP
- #include <boost/thread/detail/config.hpp>
- #include <boost/thread/exceptions.hpp>
- #include <boost/thread/lock_concepts.hpp>
- #include <boost/thread/lock_traits.hpp>
- #include <boost/thread/lockable_concepts.hpp>
- #include <boost/thread/strict_lock.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/throw_exception.hpp>
- #include <boost/core/swap.hpp>
- #include <boost/config/abi_prefix.hpp>
- namespace boost
- {
- class mutex;
- /**
- * externally_locked cloaks an object of type T, and actually provides full
- * access to that object through the get and set member functions, provided you
- * pass a reference to a strict lock object
- */
- //[externally_locked
- template <typename T, typename MutexType = boost::mutex>
- class externally_locked;
- template <typename T, typename MutexType>
- class externally_locked
- {
- //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
- BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
- public:
- typedef MutexType mutex_type;
- BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
- /**
- * Requires: T is a model of CopyConstructible.
- * Effects: Constructs an externally locked object copying the cloaked type.
- */
- externally_locked(mutex_type& mtx, const T& obj) :
- obj_(obj), mtx_(&mtx)
- {
- }
- /**
- * Requires: T is a model of Movable.
- * Effects: Constructs an externally locked object by moving the cloaked type.
- */
- externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
- obj_(move(obj)), mtx_(&mtx)
- {
- }
- /**
- * Requires: T is a model of DefaultConstructible.
- * Effects: Constructs an externally locked object initializing the cloaked type with the default constructor.
- */
- externally_locked(mutex_type& mtx) // BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T()))
- : obj_(), mtx_(&mtx)
- {
- }
- /**
- * Copy constructor
- */
- externally_locked(externally_locked const& rhs) //BOOST_NOEXCEPT
- : obj_(rhs.obj_), mtx_(rhs.mtx_)
- {
- }
- /**
- * Move constructor
- */
- externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) //BOOST_NOEXCEPT
- : obj_(move(rhs.obj_)), mtx_(rhs.mtx_)
- {
- }
- /// assignment
- externally_locked& operator=(externally_locked const& rhs) //BOOST_NOEXCEPT
- {
- obj_=rhs.obj_;
- mtx_=rhs.mtx_;
- return *this;
- }
- /// move assignment
- externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) // BOOST_NOEXCEPT
- {
- obj_=move(BOOST_THREAD_RV(rhs).obj_);
- mtx_=rhs.mtx_;
- return *this;
- }
- void swap(externally_locked& rhs) //BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR)
- {
- swap(obj_, rhs.obj_);
- swap(mtx_, rhs.mtx_);
- }
- /**
- * Requires: The lk parameter must be locking the associated mtx.
- *
- * Returns: The address of the cloaked object..
- *
- * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
- */
- T& get(strict_lock<mutex_type>& lk)
- {
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return obj_;
- }
- const T& get(strict_lock<mutex_type>& lk) const
- {
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return obj_;
- }
- template <class Lock>
- T& get(nested_strict_lock<Lock>& lk)
- {
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return obj_;
- }
- template <class Lock>
- const T& get(nested_strict_lock<Lock>& lk) const
- {
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return obj_;
- }
- /**
- * Requires: The lk parameter must be locking the associated mtx.
- * Returns: The address of the cloaked object..
- *
- * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
- */
- template <class Lock>
- T& get(Lock& lk)
- {
- BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
- BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return obj_;
- }
- mutex_type* mutex() const BOOST_NOEXCEPT
- {
- return mtx_;
- }
- // modifiers
- void lock()
- {
- mtx_->lock();
- }
- void unlock()
- {
- mtx_->unlock();
- }
- bool try_lock()
- {
- return mtx_->try_lock();
- }
- // todo add time related functions
- private:
- T obj_;
- mutex_type* mtx_;
- };
- //]
- /**
- * externally_locked<T&,M> specialization for T& that cloaks an reference to an object of type T, and actually
- * provides full access to that object through the get and set member functions, provided you
- * pass a reference to a strict lock object.
- */
- //[externally_locked_ref
- template <typename T, typename MutexType>
- class externally_locked<T&, MutexType>
- {
- //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
- BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
- public:
- typedef MutexType mutex_type;
- BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
- /**
- * Effects: Constructs an externally locked object storing the cloaked reference object.
- */
- externally_locked(T& obj, mutex_type& mtx) BOOST_NOEXCEPT :
- obj_(&obj), mtx_(&mtx)
- {
- }
- /// copy constructor
- externally_locked(externally_locked const& rhs) BOOST_NOEXCEPT :
- obj_(rhs.obj_), mtx_(rhs.mtx_)
- {
- }
- /// move constructor
- externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT :
- obj_(rhs.obj_), mtx_(rhs.mtx_)
- {
- }
- /// assignment
- externally_locked& operator=(externally_locked const& rhs) BOOST_NOEXCEPT
- {
- obj_=rhs.obj_;
- mtx_=rhs.mtx_;
- return *this;
- }
- /// move assignment
- externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT
- {
- obj_=rhs.obj_;
- mtx_=rhs.mtx_;
- return *this;
- }
- void swap(externally_locked& rhs) BOOST_NOEXCEPT
- {
- swap(obj_, rhs.obj_);
- swap(mtx_, rhs.mtx_);
- }
- /**
- * Requires: The lk parameter must be locking the associated mtx.
- *
- * Returns: The address of the cloaked object..
- *
- * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
- */
- T& get(strict_lock<mutex_type> const& lk)
- {
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return *obj_;
- }
- const T& get(strict_lock<mutex_type> const& lk) const
- {
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return *obj_;
- }
- template <class Lock>
- T& get(nested_strict_lock<Lock> const& lk)
- {
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return *obj_;
- }
- template <class Lock>
- const T& get(nested_strict_lock<Lock> const& lk) const
- {
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return *obj_;
- }
- /**
- * Requires: The lk parameter must be locking the associated mtx.
- * Returns: The address of the cloaked object..
- *
- * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
- */
- template <class Lock>
- T& get(Lock const& lk)
- {
- BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
- BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return *obj_;
- }
- /**
- * Requires: The lk parameter must be locking the associated mtx.
- * Returns: The address of the cloaked object..
- *
- * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
- */
- template <class Lock>
- T const& get(Lock const& lk) const
- {
- BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
- BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
- BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
- return *obj_;
- }
- mutex_type* mutex() const BOOST_NOEXCEPT
- {
- return mtx_;
- }
- void lock()
- {
- mtx_->lock();
- }
- void unlock()
- {
- mtx_->unlock();
- }
- bool try_lock()
- {
- return mtx_->try_lock();
- }
- // todo add time related functions
- protected:
- T* obj_;
- mutex_type* mtx_;
- };
- //]
- template <typename T, typename MutexType>
- void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs) // BOOST_NOEXCEPT
- {
- lhs.swap(rhs);
- }
- }
- #include <boost/config/abi_suffix.hpp>
- #endif // header
|