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