diff options
Diffstat (limited to 'boost/thread/externally_locked.hpp')
-rw-r--r-- | boost/thread/externally_locked.hpp | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/boost/thread/externally_locked.hpp b/boost/thread/externally_locked.hpp new file mode 100644 index 0000000000..0d4baaa512 --- /dev/null +++ b/boost/thread/externally_locked.hpp @@ -0,0 +1,351 @@ +// (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 +{ + + /** + * 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 |