CLAM-Development  1.4.0
Lock.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #ifndef __LOCK__
23 #define __LOCK__
24 
25 #include "ErrSystem.hxx"
26 #include "xtime.hxx"
27 
28 namespace CLAM
29 {
30  class Condition;
31 
32  namespace Hidden
33  {
34 
35  using CLAM::xtime;
36 
37  template <typename MutexType>
38  class LockOps
39  {
40  private:
41  LockOps() { }
42 
43  public:
44  typedef typename MutexType::ConditionVar LockState;
45 
46  static void Lock(MutexType& m)
47  {
48  m.DoLock();
49  }
50  static bool TryLock(MutexType& m)
51  {
52  return m.DoTryLock();
53  }
54  static bool TimedLock(MutexType& m, const xtime& xt)
55  {
56  return m.DoTimedLock(xt);
57  }
58  static void Unlock(MutexType& m)
59  {
60  m.DoUnlock();
61  }
62  static void Lock(MutexType& m, LockState& state)
63  {
64  m.DoLock(state);
65  }
66  static void Unlock(MutexType& m, LockState& state)
67  {
68  m.DoUnlock(state);
69  }
70  };
71 
72  template <typename MutexType>
73  class ScopedLock
74  {
75  public:
76  typedef MutexType mutex_type;
77 
78  explicit ScopedLock(MutexType& mx, bool initially_locked=true)
79  : mMutex(mx), mLocked(false)
80  {
81  if (initially_locked)
82  Lock();
83  }
85  {
86  if (mLocked)
87  Unlock();
88  }
89 
90  void Lock()
91  {
92  if (mLocked)
93  throw LockError( "Trying to Lock already locked Mutex" );
94 
96  mLocked = true;
97  }
98 
99  void Unlock()
100  {
101  if (!mLocked)
102  throw LockError("Trying to Unlock already a not yet locked Mutex");
103 
105 
106  mLocked = false;
107  }
108 
109  bool Locked() const
110  {
111  return mLocked;
112  }
113 
114  operator const void*() const
115  {
116  return mLocked ? this : 0;
117  }
118 
119  private:
120  friend class CLAM::Condition;
121 
122  MutexType& mMutex;
123  bool mLocked;
124  };
125 
126  template <typename TryMutexType>
128  {
129  public:
130  typedef TryMutexType mutex_type;
131 
132  explicit ScopedTryLock(TryMutexType& mx)
133  : mMutex(mx), mLocked(false)
134  {
135  TryLock();
136  }
137 
138  ScopedTryLock(TryMutexType& mx, bool initially_locked)
139  : mMutex(mx), mLocked(false)
140  {
141  if (initially_locked)
142  Lock();
143  }
144 
146  {
147  if (mLocked)
148  Unlock();
149  }
150 
151  void Lock()
152  {
153  if (mLocked)
154  throw LockError("Trying to Lock already locked Mutex");
155 
157 
158  mLocked = true;
159  }
160 
161  bool TryLock()
162  {
163  if (mLocked)
164  throw LockError("Trying to Lock already locked Mutex");
165 
166  return (mLocked = LockOps<TryMutexType>::TryLock(mMutex));
167  }
168 
169  void Unlock()
170  {
171  if (!mLocked)
172  throw LockError("Trying to Unlock already a not yet locked Mutex");
173 
175 
176  mLocked = false;
177  }
178 
179  bool Locked() const
180  {
181  return mLocked;
182  }
183 
184  operator const void*() const
185  {
186  return mLocked ? this : 0;
187  }
188 
189  private:
190 
191  friend class CLAM::Condition;
192 
193  TryMutexType& mMutex;
194  bool mLocked;
195  };
196 
197  template <typename TimedMutexType>
199  {
200  public:
201  typedef TimedMutexType mutex_type;
202 
203  ScopedTimedLock(TimedMutexType& mx, const xtime& xt )
204  : mMutex(mx), mLocked(false)
205  {
206 
207  TimedLock(xt);
208  }
209 
210  ScopedTimedLock(TimedMutexType& mx, bool initially_locked)
211  : mMutex(mx), mLocked(false)
212  {
213  if (initially_locked)
214  Lock();
215  }
216 
218  {
219  if (mLocked)
220  Unlock();
221  }
222 
223  void Lock()
224  {
225  if (mLocked)
226  throw LockError("Trying to Lock already locked Mutex");
227 
229 
230  mLocked = true;
231  }
232 
233  bool TimedLock(const xtime& xt)
234  {
235  if (mLocked)
236  throw LockError("Trying to Lock already locked Mutex");
237 
238  return (mLocked = LockOps<TimedMutexType>::TimedLock(mMutex, xt));
239  }
240  void Unlock()
241  {
242  if (!mLocked)
243  throw LockError("Trying to Unlock already a not yet locked Mutex");
244 
246 
247  mLocked = false;
248  }
249 
250  bool Locked() const
251  {
252  return mLocked;
253  }
254 
255  operator const void*() const
256  {
257  return mLocked ? this : 0;
258  }
259 
260  private:
261 
262  friend class CLAM::Condition;
263 
264  TimedMutexType& mMutex;
265  bool mLocked;
266  };
267 
268  } // End of namespace Hidden
269 
270 } // end of namespace CLAM
271 
272 #endif // Lock.hxx
273