| 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
 |