Chris@16: // (C) Copyright 2012 Vicente Botet Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP Chris@16: #define BOOST_THREAD_LOCK_CONCEPTS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: /** Chris@16: * BasicLock object supports the basic features Chris@16: * required to delimit a critical region Chris@16: * Supports the basic lock, unlock and try_lock functions and Chris@16: * defines the lock traits Chris@16: */ Chris@16: Chris@16: template Chris@16: struct BasicLock Chris@16: { Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: void cvt_mutex_ptr(mutex_type*) {} Chris@16: BOOST_CONCEPT_ASSERT(( BasicLockable )); Chris@16: Chris@16: BOOST_CONCEPT_USAGE(BasicLock) Chris@16: { Chris@16: const Lk l1(mtx); Chris@16: Lk l2(mtx, defer_lock); Chris@16: Lk l3(mtx, adopt_lock); Chris@16: Lk l4(( Lk())); Chris@16: Lk l5(( boost::move(l2))); Chris@16: cvt_mutex_ptr(l1.mutex()); Chris@16: if (l1.owns_lock()) return; Chris@16: if (l1) return; Chris@16: if (!l1) return; Chris@16: Chris@16: l2.lock(); Chris@16: l2.unlock(); Chris@16: l2.release(); Chris@16: Chris@16: } Chris@16: BasicLock() : Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: BasicLock operator=(BasicLock const&); Chris@16: mutex_type& mtx; Chris@16: } Chris@16: ; Chris@16: Chris@16: template Chris@16: struct Lock Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( BasicLock )); Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: BOOST_CONCEPT_ASSERT(( Lockable )); Chris@16: Chris@16: BOOST_CONCEPT_USAGE(Lock) Chris@16: { Chris@16: Lk l1(mtx, try_to_lock); Chris@16: if (l1.try_lock()) return; Chris@16: } Chris@16: Lock() : Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: Lock operator=(Lock const&); Chris@16: mutex_type& mtx; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct TimedLock Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( Lock )); Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: BOOST_CONCEPT_ASSERT(( TimedLockable )); Chris@16: Chris@16: BOOST_CONCEPT_USAGE(TimedLock) Chris@16: { Chris@16: const Lk l1(mtx, t); Chris@16: Lk l2(mtx, d); Chris@16: if (l1.try_lock_until(t)) return; Chris@16: if (l1.try_lock_for(d)) return; Chris@16: } Chris@16: TimedLock() : Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: TimedLock operator=(TimedLock const&); Chris@16: mutex_type& mtx; Chris@16: boost::chrono::system_clock::time_point t; Chris@16: boost::chrono::system_clock::duration d; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct UniqueLock Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( TimedLock )); Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(UniqueLock) Chris@16: { Chris@16: Chris@16: } Chris@16: UniqueLock() : Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: UniqueLock operator=(UniqueLock const&); Chris@16: mutex_type& mtx; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct SharedLock Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( TimedLock )); Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(SharedLock) Chris@16: { Chris@16: } Chris@16: SharedLock() : Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: SharedLock operator=(SharedLock const&); Chris@16: mutex_type& mtx; Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: struct UpgradeLock Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( SharedLock )); Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(UpgradeLock) Chris@16: { Chris@16: } Chris@16: UpgradeLock() : Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: UpgradeLock operator=(UpgradeLock const&); Chris@16: mutex_type& mtx; Chris@16: }; Chris@16: Chris@16: /** Chris@16: * An StrictLock is a scoped lock guard ensuring the mutex is locked on the Chris@16: * scope of the lock, by locking the mutex on construction and unlocking it on Chris@16: * destruction. Chris@16: * Chris@16: * Essentially, a StrictLock's role is only to live on the stack as an Chris@16: * automatic variable. strict_lock must adhere to a non-copy and non-alias Chris@16: * policy. StrictLock disables copying by making the copy constructor and the Chris@16: * assignment operator private. While we're at it, let's disable operator new Chris@16: * and operator delete; strict locks are not intended to be allocated on the Chris@16: * heap. StrictLock avoids aliasing by using a slightly less orthodox and Chris@16: * less well-known technique: disable address taking. Chris@16: */ Chris@16: Chris@16: template Chris@16: struct StrictLock Chris@16: { Chris@16: typedef typename Lk::mutex_type mutex_type; Chris@16: BOOST_CONCEPT_ASSERT(( BasicLockable )); Chris@16: BOOST_STATIC_ASSERT(( is_strict_lock::value )); Chris@16: Chris@16: BOOST_CONCEPT_USAGE( StrictLock) Chris@16: { Chris@16: if (l1.owns_lock(&mtx)) return; Chris@16: } Chris@16: StrictLock() : Chris@16: l1(*static_cast(0)), Chris@16: mtx(*static_cast(0)) Chris@16: {} Chris@16: private: Chris@16: StrictLock operator=(StrictLock const&); Chris@16: Chris@16: Lk const& l1; Chris@16: mutex_type const& mtx; Chris@16: Chris@16: }; Chris@16: Chris@16: } Chris@16: #endif