• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // (C) Copyright 2012 Vicente Botet
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP
7 #define BOOST_THREAD_LOCK_CONCEPTS_HPP
8 
9 #include <boost/thread/lock_traits.hpp>
10 #include <boost/thread/lock_options.hpp>
11 #include <boost/thread/lockable_concepts.hpp>
12 #include <boost/thread/exceptions.hpp>
13 #include <boost/thread/detail/move.hpp>
14 
15 #include <boost/chrono/chrono.hpp>
16 #include <boost/concept_check.hpp>
17 #include <boost/static_assert.hpp>
18 
19 namespace boost
20 {
21 
22   /**
23    * BasicLock object supports the basic features
24    * required to delimit a critical region
25    * Supports the basic lock, unlock and try_lock functions and
26    * defines the lock traits
27    */
28 
29   template <typename Lk>
30   struct BasicLock
31   {
32     typedef typename Lk::mutex_type mutex_type;
cvt_mutex_ptrboost::BasicLock33     void cvt_mutex_ptr(mutex_type*) {}
34     BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
35 
BOOST_CONCEPT_USAGEboost::BasicLock36     BOOST_CONCEPT_USAGE(BasicLock)
37     {
38       const Lk l1(mtx);
39       Lk l2(mtx, defer_lock);
40       Lk l3(mtx, adopt_lock);
41       Lk l4(( Lk()));
42       Lk l5(( boost::move(l2)));
43       cvt_mutex_ptr(l1.mutex());
44       if (l1.owns_lock()) return;
45       if (l1) return;
46       if (!l1) return;
47 
48       l2.lock();
49       l2.unlock();
50       l2.release();
51 
52     }
BasicLockboost::BasicLock53     BasicLock() :
54       mtx(*static_cast<mutex_type*>(0))
55     {}
56   private:
57     BasicLock operator=(BasicLock const&);
58     mutex_type& mtx;
59   }
60   ;
61 
62   template <typename Lk>
63   struct Lock
64   {
65     BOOST_CONCEPT_ASSERT(( BasicLock<Lk> ));
66     typedef typename Lk::mutex_type mutex_type;
67     BOOST_CONCEPT_ASSERT(( Lockable<mutex_type> ));
68 
BOOST_CONCEPT_USAGEboost::Lock69     BOOST_CONCEPT_USAGE(Lock)
70     {
71       Lk l1(mtx, try_to_lock);
72       if (l1.try_lock()) return;
73     }
Lockboost::Lock74     Lock() :
75       mtx(*static_cast<mutex_type*>(0))
76     {}
77   private:
78     Lock operator=(Lock const&);
79     mutex_type& mtx;
80   };
81 
82   template <typename Lk>
83   struct TimedLock
84   {
85     BOOST_CONCEPT_ASSERT(( Lock<Lk> ));
86     typedef typename Lk::mutex_type mutex_type;
87     BOOST_CONCEPT_ASSERT(( TimedLockable<mutex_type> ));
88 
BOOST_CONCEPT_USAGEboost::TimedLock89     BOOST_CONCEPT_USAGE(TimedLock)
90     {
91       const Lk l1(mtx, t);
92       Lk l2(mtx, d);
93       if (l1.try_lock_until(t)) return;
94       if (l1.try_lock_for(d)) return;
95     }
TimedLockboost::TimedLock96     TimedLock() :
97       mtx(*static_cast<mutex_type*>(0))
98     {}
99   private:
100     TimedLock operator=(TimedLock const&);
101     mutex_type& mtx;
102     boost::chrono::system_clock::time_point t;
103     boost::chrono::system_clock::duration d;
104   };
105 
106   template <typename Lk>
107   struct UniqueLock
108   {
109     BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
110     typedef typename Lk::mutex_type mutex_type;
111 
BOOST_CONCEPT_USAGEboost::UniqueLock112     BOOST_CONCEPT_USAGE(UniqueLock)
113     {
114 
115     }
UniqueLockboost::UniqueLock116     UniqueLock() :
117       mtx(*static_cast<mutex_type*>(0))
118     {}
119   private:
120     UniqueLock operator=(UniqueLock const&);
121     mutex_type& mtx;
122   };
123 
124   template <typename Lk>
125   struct SharedLock
126   {
127     BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
128     typedef typename Lk::mutex_type mutex_type;
129 
BOOST_CONCEPT_USAGEboost::SharedLock130     BOOST_CONCEPT_USAGE(SharedLock)
131     {
132     }
SharedLockboost::SharedLock133     SharedLock() :
134       mtx(*static_cast<mutex_type*>(0))
135     {}
136   private:
137     SharedLock operator=(SharedLock const&);
138     mutex_type& mtx;
139 
140   };
141 
142   template <typename Lk>
143   struct UpgradeLock
144   {
145     BOOST_CONCEPT_ASSERT(( SharedLock<Lk> ));
146     typedef typename Lk::mutex_type mutex_type;
147 
BOOST_CONCEPT_USAGEboost::UpgradeLock148     BOOST_CONCEPT_USAGE(UpgradeLock)
149     {
150     }
UpgradeLockboost::UpgradeLock151     UpgradeLock() :
152       mtx(*static_cast<mutex_type*>(0))
153     {}
154   private:
155     UpgradeLock operator=(UpgradeLock const&);
156     mutex_type& mtx;
157   };
158 
159   /**
160    * An StrictLock is a scoped lock guard ensuring the mutex is locked on the
161    * scope of the lock, by locking the mutex on construction and unlocking it on
162    * destruction.
163    *
164    * Essentially, a StrictLock's role is only to live on the stack as an
165    * automatic variable. strict_lock must adhere to a non-copy and non-alias
166    * policy. StrictLock disables copying by making the copy constructor and the
167    * assignment operator private. While we're at it, let's disable operator new
168    * and operator delete; strict locks are not intended to be allocated on the
169    * heap. StrictLock avoids aliasing by using a slightly less orthodox and
170    * less well-known technique: disable address taking.
171    */
172 
173   template <typename Lk>
174   struct StrictLock
175   {
176     typedef typename Lk::mutex_type mutex_type;
177     BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
178     BOOST_STATIC_ASSERT(( is_strict_lock<Lk>::value ));
179 
BOOST_CONCEPT_USAGEboost::StrictLock180     BOOST_CONCEPT_USAGE( StrictLock)
181     {
182       if (l1.owns_lock(&mtx)) return;
183     }
StrictLockboost::StrictLock184     StrictLock() :
185       l1(*static_cast<Lk*>(0)),
186       mtx(*static_cast<mutex_type*>(0))
187     {}
188   private:
189     StrictLock operator=(StrictLock const&);
190 
191     Lk const& l1;
192     mutex_type const& mtx;
193 
194   };
195 
196 }
197 #endif
198