Lock.hxx

Go to the documentation of this file.
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 
Generated by  doxygen 1.6.3