Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:30

0001 // (C) Copyright 2012 Vicente Botet
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP
0007 #define BOOST_THREAD_LOCK_CONCEPTS_HPP
0008 
0009 #include <boost/thread/lock_traits.hpp>
0010 #include <boost/thread/lock_options.hpp>
0011 #include <boost/thread/lockable_concepts.hpp>
0012 #include <boost/thread/exceptions.hpp>
0013 #include <boost/thread/detail/move.hpp>
0014 
0015 #include <boost/chrono/chrono.hpp>
0016 #include <boost/concept_check.hpp>
0017 #include <boost/static_assert.hpp>
0018 
0019 namespace boost
0020 {
0021 
0022   /**
0023    * BasicLock object supports the basic features
0024    * required to delimit a critical region
0025    * Supports the basic lock, unlock and try_lock functions and
0026    * defines the lock traits
0027    */
0028 
0029   template <typename Lk>
0030   struct BasicLock
0031   {
0032     typedef typename Lk::mutex_type mutex_type;
0033     void cvt_mutex_ptr(mutex_type*) {}
0034     BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
0035 
0036     BOOST_CONCEPT_USAGE(BasicLock)
0037     {
0038       const Lk l1(mtx);
0039       Lk l2(mtx, defer_lock);
0040       Lk l3(mtx, adopt_lock);
0041       Lk l4(( Lk()));
0042       Lk l5(( boost::move(l2)));
0043       cvt_mutex_ptr(l1.mutex());
0044       if (l1.owns_lock()) return;
0045       if (l1) return;
0046       if (!l1) return;
0047 
0048       l2.lock();
0049       l2.unlock();
0050       l2.release();
0051 
0052     }
0053     BasicLock() :
0054       mtx(*static_cast<mutex_type*>(0))
0055     {}
0056   private:
0057     BasicLock operator=(BasicLock const&);
0058     mutex_type& mtx;
0059   }
0060   ;
0061 
0062   template <typename Lk>
0063   struct Lock
0064   {
0065     BOOST_CONCEPT_ASSERT(( BasicLock<Lk> ));
0066     typedef typename Lk::mutex_type mutex_type;
0067     BOOST_CONCEPT_ASSERT(( Lockable<mutex_type> ));
0068 
0069     BOOST_CONCEPT_USAGE(Lock)
0070     {
0071       Lk l1(mtx, try_to_lock);
0072       if (l1.try_lock()) return;
0073     }
0074     Lock() :
0075       mtx(*static_cast<mutex_type*>(0))
0076     {}
0077   private:
0078     Lock operator=(Lock const&);
0079     mutex_type& mtx;
0080   };
0081 
0082   template <typename Lk>
0083   struct TimedLock
0084   {
0085     BOOST_CONCEPT_ASSERT(( Lock<Lk> ));
0086     typedef typename Lk::mutex_type mutex_type;
0087     BOOST_CONCEPT_ASSERT(( TimedLockable<mutex_type> ));
0088 
0089     BOOST_CONCEPT_USAGE(TimedLock)
0090     {
0091       const Lk l1(mtx, t);
0092       Lk l2(mtx, d);
0093       if (l1.try_lock_until(t)) return;
0094       if (l1.try_lock_for(d)) return;
0095     }
0096     TimedLock() :
0097       mtx(*static_cast<mutex_type*>(0))
0098     {}
0099   private:
0100     TimedLock operator=(TimedLock const&);
0101     mutex_type& mtx;
0102     boost::chrono::system_clock::time_point t;
0103     boost::chrono::system_clock::duration d;
0104   };
0105 
0106   template <typename Lk>
0107   struct UniqueLock
0108   {
0109     BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
0110     typedef typename Lk::mutex_type mutex_type;
0111 
0112     BOOST_CONCEPT_USAGE(UniqueLock)
0113     {
0114 
0115     }
0116     UniqueLock() :
0117       mtx(*static_cast<mutex_type*>(0))
0118     {}
0119   private:
0120     UniqueLock operator=(UniqueLock const&);
0121     mutex_type& mtx;
0122   };
0123 
0124   template <typename Lk>
0125   struct SharedLock
0126   {
0127     BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
0128     typedef typename Lk::mutex_type mutex_type;
0129 
0130     BOOST_CONCEPT_USAGE(SharedLock)
0131     {
0132     }
0133     SharedLock() :
0134       mtx(*static_cast<mutex_type*>(0))
0135     {}
0136   private:
0137     SharedLock operator=(SharedLock const&);
0138     mutex_type& mtx;
0139 
0140   };
0141 
0142   template <typename Lk>
0143   struct UpgradeLock
0144   {
0145     BOOST_CONCEPT_ASSERT(( SharedLock<Lk> ));
0146     typedef typename Lk::mutex_type mutex_type;
0147 
0148     BOOST_CONCEPT_USAGE(UpgradeLock)
0149     {
0150     }
0151     UpgradeLock() :
0152       mtx(*static_cast<mutex_type*>(0))
0153     {}
0154   private:
0155     UpgradeLock operator=(UpgradeLock const&);
0156     mutex_type& mtx;
0157   };
0158 
0159   /**
0160    * An StrictLock is a scoped lock guard ensuring the mutex is locked on the
0161    * scope of the lock, by locking the mutex on construction and unlocking it on
0162    * destruction.
0163    *
0164    * Essentially, a StrictLock's role is only to live on the stack as an
0165    * automatic variable. strict_lock must adhere to a non-copy and non-alias
0166    * policy. StrictLock disables copying by making the copy constructor and the
0167    * assignment operator private. While we're at it, let's disable operator new
0168    * and operator delete; strict locks are not intended to be allocated on the
0169    * heap. StrictLock avoids aliasing by using a slightly less orthodox and
0170    * less well-known technique: disable address taking.
0171    */
0172 
0173   template <typename Lk>
0174   struct StrictLock
0175   {
0176     typedef typename Lk::mutex_type mutex_type;
0177     BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
0178     BOOST_STATIC_ASSERT(( is_strict_lock<Lk>::value ));
0179 
0180     BOOST_CONCEPT_USAGE( StrictLock)
0181     {
0182       if (l1.owns_lock(&mtx)) return;
0183     }
0184     StrictLock() :
0185       l1(*static_cast<Lk*>(0)),
0186       mtx(*static_cast<mutex_type*>(0))
0187     {}
0188   private:
0189     StrictLock operator=(StrictLock const&);
0190 
0191     Lk const& l1;
0192     mutex_type const& mtx;
0193 
0194   };
0195 
0196 }
0197 #endif