libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
locking_impl.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace ppd { namespace lock {
20 
21  template<class Lk> inline typename lockable<Lk>::atomic_state_type
22  lockable<Lk>::try_lock() noexcept(true) {
23  assert(dynamic_cast<lockable *>(this));
24  return this->lock(0);
25  }
26 
27  template<class Lk> inline
28  boost_lk_compat<Lk>::boost_lk_compat(atomic_t &l) noexcept(true)
29  : lk(l) {
30  }
31 
32  template<class Lk> inline bool
33  boost_lk_compat<Lk>::try_lock() noexcept(noexcept(lk.try_lock())) {
34  assert(dynamic_cast<atomic_t *>(&lk));
35  return lk.try_lock()==lock_traits::atom_set;
36  }
37 
38  template<class Lk> inline void
39  boost_lk_compat<Lk>::lock() noexcept(noexcept(lk.lock())) {
40  [[maybe_unused]] const typename atomic_t::atomic_state_type ret=lk.lock();
41  assert(ret==atomic_t::atom_set);
42  }
43 
44  template<class Lk> inline void
45  boost_lk_compat<Lk>::unlock() noexcept(noexcept(lk.unlock())) {
46  lk.unlock();
47  }
48 
49  template<class LockObject> inline
50  scope_lock<LockObject>::scope_lock(atomic_t &lo) noexcept(true)
51  : locker(lo) {
52  }
53 
54  template<class LockObject> inline typename scope_lock<LockObject>::atomic_state_type
55  scope_lock<LockObject>::try_lock() noexcept(true) {
56  assert(dynamic_cast<atomic_t *>(&locker));
57  return locker.try_lock();
58  }
59 
60  template<class LockObject> inline typename scope_lock<LockObject>::atomic_state_type
61  scope_lock<LockObject>::lock() noexcept(false) {
62  assert(dynamic_cast<atomic_t *>(&locker));
63  return locker.lock();
64  }
65 
66  template<class LockObject> inline typename scope_lock<LockObject>::atomic_state_type
67  scope_lock<LockObject>::lock(const timeout_type period) noexcept(false) {
68  assert(dynamic_cast<atomic_t *>(&locker));
69  return locker.lock(period);
70  }
71 
72  template<class LockObject> inline typename scope_lock<LockObject>::atomic_state_type
73  scope_lock<LockObject>::unlock() noexcept(true) {
74  assert(dynamic_cast<atomic_t *>(&locker));
75  return locker.unlock();
76  }
77 
78  template<class LockObject> inline
79  scope_lock<LockObject>::scope_lock(atomic_t &lo, const timeout_type period) noexcept(true)
80  : locker(lo) {
81  [[maybe_unused]] const typename atomic_t::atomic_state_type ret=lock(period);
82  assert(ret==atomic_t::lock_traits::atom_set);
83  }
84 
85  template<class LockObject> inline
86  scope_lock<LockObject>::~scope_lock() noexcept(true) {
87  unlock();
88  }
89 
90  template<class LockObject> inline void
91  scope_lock<LockObject>::decay() noexcept(true) {
92  assert(dynamic_cast<atomic_t *>(&locker));
93  return locker.decay();
94  }
95 
96  template<class LockObject> inline
97  in_process<LockObject>::in_process(atomic_t &lo, const timeout_type period) noexcept(true)
98  : scope_lock<LockObject>(lo,period) {
99  }
100 
101  template<class LockObject> inline
102  in_process<LockObject>::~in_process() noexcept(true) {
103  }
104 
105  template<class LockObject> inline typename in_process<LockObject>::atomic_state_type
106  in_process<LockObject>::try_lock() noexcept(true) {
107  assert(dynamic_cast<atomic_t *>(&this->locker));
108  return this->locker.try_lock();
109  }
110 
111  template<class LockObject> inline typename in_process<LockObject>::atomic_state_type
112  in_process<LockObject>::lock() noexcept(false) {
113  assert(dynamic_cast<atomic_t *>(&this->locker));
114  return this->locker.lock();
115  }
116 
117  template<class LockObject> inline typename in_process<LockObject>::atomic_state_type
118  in_process<LockObject>::lock(const timeout_type period) noexcept(false) {
119  assert(dynamic_cast<atomic_t *>(&this->locker));
120  return this->locker.lock(period);
121  }
122 
123  template<class LockObject> inline typename in_process<LockObject>::atomic_state_type
124  in_process<LockObject>::unlock() noexcept(true) {
125  assert(dynamic_cast<atomic_t *>(&this->locker));
126  return this->locker.unlock();
127  }
128 
129  template<class LockObject> inline void
130  in_process<LockObject>::decay() noexcept(true) {
131  assert(dynamic_cast<atomic_t *>(&this->locker));
132  return this->locker.decay();
133  }
134 
135  template<class LockObject> inline
136  in_process_unlockable<LockObject>::in_process_unlockable(atomic_t &lo) noexcept(true)
137  : locker(lo), locked(false) {
138  }
139 
140  template<class LockObject> inline
141  in_process_unlockable<LockObject>::in_process_unlockable(atomic_t &lo, const timeout_type period) noexcept(true)
142  : locker(lo), locked(false) {
143  const typename atomic_t::atomic_state_type ret=this->locker.lock(period);
144  locked=(ret==atomic_t::lock_traits::atom_set);
145  }
146 
147  template<class LockObject> inline typename in_process_unlockable<LockObject>::atomic_state_type
148  in_process_unlockable<LockObject>::unlock() noexcept(true) {
149  assert(dynamic_cast<atomic_t *>(&this->locker));
150  locked=false;
151  return this->locker.unlock();
152  }
153 
154  template<class LockObject> inline
155  in_process_unlockable<LockObject>::~in_process_unlockable() noexcept(true) {
156  if (locked) {
157  unlock();
158  locked=false;
159  }
160  }
161 
162  template<class LockObject> inline typename in_process_unlockable<LockObject>::atomic_state_type
163  in_process_unlockable<LockObject>::try_lock() noexcept(true) {
164  assert(dynamic_cast<atomic_t *>(&this->locker));
165  const typename atomic_t::atomic_state_type ret=this->locker.try_lock();
166  locked=(ret==atomic_t::lock_traits::atom_set);
167  return ret;
168  }
169 
170  template<class LockObject> inline void
171  in_process_unlockable<LockObject>::decay() noexcept(true) {
172  assert(dynamic_cast<atomic_t *>(&this->locker));
173  locked=false;
174  return this->locker.decay();
175  }
176 
177 namespace any_order {
178 
179  template<generic_traits::api_type API_, typename Mdl_, class Lk1, class Lk2> inline
180  all<API_, Mdl_, Lk1, Lk2>::all(first_argument_type &l1, second_argument_type &l2) noexcept(noexcept(boost::lock(std::declval<first_argument_type>(), std::declval<second_argument_type>())))
181  : lk1(l1), lk2(l2) {
182  boost::lock(lk1, lk2);
183  }
184 
185  template<generic_traits::api_type API_,typename Mdl_,class Lk1,class Lk2> inline
186  all<API_,Mdl_,Lk1,Lk2>::~all() noexcept(true) {
187  lk1.unlock();
188  lk2.unlock();
189  }
190 
191  template<generic_traits::api_type API_, typename Mdl_, class Lk1, class Lk2> inline
192  try_one<API_, Mdl_, Lk1, Lk2>::try_one(Lk1 &l1, Lk2 &l2) noexcept(true)
193  : lk1(l1), lk2(l2) {
194  }
195 
196  template<generic_traits::api_type API_,typename Mdl_,class Lk1,class Lk2> inline typename try_one<API_,Mdl_,Lk1,Lk2>::result_type
197  try_one<API_,Mdl_,Lk1,Lk2>::try_lock() noexcept(noexcept(boost::try_lock(std::declval<Lk1>(), std::declval<Lk2>()))) {
198  return boost::try_lock(lk1,lk2);
199  }
200 
201 }
202 
203 } } } }