Lock.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __LOCK__
00023 #define __LOCK__
00024
00025 #include "ErrSystem.hxx"
00026 #include "xtime.hxx"
00027
00028 namespace CLAM
00029 {
00030 class Condition;
00031
00032 namespace Hidden
00033 {
00034
00035 using CLAM::xtime;
00036
00037 template <typename MutexType>
00038 class LockOps
00039 {
00040 private:
00041 LockOps() { }
00042
00043 public:
00044 typedef typename MutexType::ConditionVar LockState;
00045
00046 static void Lock(MutexType& m)
00047 {
00048 m.DoLock();
00049 }
00050 static bool TryLock(MutexType& m)
00051 {
00052 return m.DoTryLock();
00053 }
00054 static bool TimedLock(MutexType& m, const xtime& xt)
00055 {
00056 return m.DoTimedLock(xt);
00057 }
00058 static void Unlock(MutexType& m)
00059 {
00060 m.DoUnlock();
00061 }
00062 static void Lock(MutexType& m, LockState& state)
00063 {
00064 m.DoLock(state);
00065 }
00066 static void Unlock(MutexType& m, LockState& state)
00067 {
00068 m.DoUnlock(state);
00069 }
00070 };
00071
00072 template <typename MutexType>
00073 class ScopedLock
00074 {
00075 public:
00076 typedef MutexType mutex_type;
00077
00078 explicit ScopedLock(MutexType& mx, bool initially_locked=true)
00079 : mMutex(mx), mLocked(false)
00080 {
00081 if (initially_locked)
00082 Lock();
00083 }
00084 ~ScopedLock()
00085 {
00086 if (mLocked)
00087 Unlock();
00088 }
00089
00090 void Lock()
00091 {
00092 if (mLocked)
00093 throw LockError( "Trying to Lock already locked Mutex" );
00094
00095 Hidden::LockOps<mutex_type>::Lock(mMutex);
00096 mLocked = true;
00097 }
00098
00099 void Unlock()
00100 {
00101 if (!mLocked)
00102 throw LockError("Trying to Unlock already a not yet locked Mutex");
00103
00104 LockOps<mutex_type>::Unlock(mMutex);
00105
00106 mLocked = false;
00107 }
00108
00109 bool Locked() const
00110 {
00111 return mLocked;
00112 }
00113
00114 operator const void*() const
00115 {
00116 return mLocked ? this : 0;
00117 }
00118
00119 private:
00120 friend class CLAM::Condition;
00121
00122 MutexType& mMutex;
00123 bool mLocked;
00124 };
00125
00126 template <typename TryMutexType>
00127 class ScopedTryLock
00128 {
00129 public:
00130 typedef TryMutexType mutex_type;
00131
00132 explicit ScopedTryLock(TryMutexType& mx)
00133 : mMutex(mx), mLocked(false)
00134 {
00135 TryLock();
00136 }
00137
00138 ScopedTryLock(TryMutexType& mx, bool initially_locked)
00139 : mMutex(mx), mLocked(false)
00140 {
00141 if (initially_locked)
00142 Lock();
00143 }
00144
00145 ~ScopedTryLock()
00146 {
00147 if (mLocked)
00148 Unlock();
00149 }
00150
00151 void Lock()
00152 {
00153 if (mLocked)
00154 throw LockError("Trying to Lock already locked Mutex");
00155
00156 LockOps<TryMutexType>::Lock(mMutex);
00157
00158 mLocked = true;
00159 }
00160
00161 bool TryLock()
00162 {
00163 if (mLocked)
00164 throw LockError("Trying to Lock already locked Mutex");
00165
00166 return (mLocked = LockOps<TryMutexType>::TryLock(mMutex));
00167 }
00168
00169 void Unlock()
00170 {
00171 if (!mLocked)
00172 throw LockError("Trying to Unlock already a not yet locked Mutex");
00173
00174 LockOps<TryMutexType>::Unlock(mMutex);
00175
00176 mLocked = false;
00177 }
00178
00179 bool Locked() const
00180 {
00181 return mLocked;
00182 }
00183
00184 operator const void*() const
00185 {
00186 return mLocked ? this : 0;
00187 }
00188
00189 private:
00190
00191 friend class CLAM::Condition;
00192
00193 TryMutexType& mMutex;
00194 bool mLocked;
00195 };
00196
00197 template <typename TimedMutexType>
00198 class ScopedTimedLock
00199 {
00200 public:
00201 typedef TimedMutexType mutex_type;
00202
00203 ScopedTimedLock(TimedMutexType& mx, const xtime& xt )
00204 : mMutex(mx), mLocked(false)
00205 {
00206
00207 TimedLock(xt);
00208 }
00209
00210 ScopedTimedLock(TimedMutexType& mx, bool initially_locked)
00211 : mMutex(mx), mLocked(false)
00212 {
00213 if (initially_locked)
00214 Lock();
00215 }
00216
00217 ~ScopedTimedLock()
00218 {
00219 if (mLocked)
00220 Unlock();
00221 }
00222
00223 void Lock()
00224 {
00225 if (mLocked)
00226 throw LockError("Trying to Lock already locked Mutex");
00227
00228 LockOps<TimedMutexType>::Lock(mMutex);
00229
00230 mLocked = true;
00231 }
00232
00233 bool TimedLock(const xtime& xt)
00234 {
00235 if (mLocked)
00236 throw LockError("Trying to Lock already locked Mutex");
00237
00238 return (mLocked = LockOps<TimedMutexType>::TimedLock(mMutex, xt));
00239 }
00240 void Unlock()
00241 {
00242 if (!mLocked)
00243 throw LockError("Trying to Unlock already a not yet locked Mutex");
00244
00245 LockOps<TimedMutexType>::Unlock(mMutex);
00246
00247 mLocked = false;
00248 }
00249
00250 bool Locked() const
00251 {
00252 return mLocked;
00253 }
00254
00255 operator const void*() const
00256 {
00257 return mLocked ? this : 0;
00258 }
00259
00260 private:
00261
00262 friend class CLAM::Condition;
00263
00264 TimedMutexType& mMutex;
00265 bool mLocked;
00266 };
00267
00268 }
00269
00270 }
00271
00272 #endif // Lock.hxx
00273