CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 } // End of namespace Hidden 00269 00270 } // end of namespace CLAM 00271 00272 #endif // Lock.hxx 00273