00001 // @(#)root/base:$Id: TVirtualMutex.h 25230 2008-08-25 15:22:04Z rdm $ 00002 // Author: Fons Rademakers 14/07/2002 00003 00004 /************************************************************************* 00005 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * 00006 * All rights reserved. * 00007 * * 00008 * For the licensing terms see $ROOTSYS/LICENSE. * 00009 * For the list of contributors see $ROOTSYS/README/CREDITS. * 00010 *************************************************************************/ 00011 00012 #ifndef ROOT_TVirtualMutex 00013 #define ROOT_TVirtualMutex 00014 00015 00016 ////////////////////////////////////////////////////////////////////////// 00017 // // 00018 // TVirtualMutex // 00019 // // 00020 // This class implements a mutex interface. The actual work is done via // 00021 // TMutex which is available as soon as the thread library is loaded. // 00022 // // 00023 ////////////////////////////////////////////////////////////////////////// 00024 00025 #ifndef ROOT_TObject 00026 #include "TObject.h" 00027 #endif 00028 00029 class TVirtualMutex; 00030 00031 // Global mutex set in TThread::Init 00032 R__EXTERN TVirtualMutex *gGlobalMutex; 00033 00034 class TVirtualMutex : public TObject { 00035 00036 public: 00037 TVirtualMutex(Bool_t /* recursive */ = kFALSE) { } 00038 virtual ~TVirtualMutex() { } 00039 00040 virtual Int_t Lock() = 0; 00041 virtual Int_t TryLock() = 0; 00042 virtual Int_t UnLock() = 0; 00043 virtual Int_t CleanUp() = 0; 00044 Int_t Acquire() { return Lock(); } 00045 Int_t Release() { return UnLock(); } 00046 00047 virtual TVirtualMutex *Factory(Bool_t /*recursive*/ = kFALSE) = 0; 00048 00049 ClassDef(TVirtualMutex,0) // Virtual mutex lock class 00050 }; 00051 00052 00053 ////////////////////////////////////////////////////////////////////////// 00054 // // 00055 // TLockGuard // 00056 // // 00057 // This class provides mutex resource management in a guaranteed and // 00058 // exception safe way. Use like this: // 00059 // { // 00060 // TLockGuard guard(mutex); // 00061 // ... // do something // 00062 // } // 00063 // when guard goes out of scope the mutex is unlocked in the TLockGuard // 00064 // destructor. The exception mechanism takes care of calling the dtors // 00065 // of local objects so it is exception safe. // 00066 // // 00067 ////////////////////////////////////////////////////////////////////////// 00068 00069 class TLockGuard { 00070 00071 private: 00072 TVirtualMutex *fMutex; 00073 00074 TLockGuard(const TLockGuard&); // not implemented 00075 TLockGuard& operator=(const TLockGuard&); // not implemented 00076 00077 public: 00078 TLockGuard(TVirtualMutex *mutex) 00079 : fMutex(mutex) { if (fMutex) fMutex->Lock(); } 00080 virtual ~TLockGuard() { if (fMutex) fMutex->UnLock(); } 00081 00082 ClassDef(TLockGuard,0) // Exception safe locking/unlocking of mutex 00083 }; 00084 00085 // Zero overhead macros in case not compiled with thread support 00086 #if defined (_REENTRANT) || defined (WIN32) 00087 #define R__LOCKGUARD(mutex) TLockGuard _R__UNIQUE_(R__guard)(mutex) 00088 #define R__LOCKGUARD2(mutex) \ 00089 if (gGlobalMutex && !mutex) { \ 00090 gGlobalMutex->Lock(); \ 00091 if (!mutex) \ 00092 mutex = gGlobalMutex->Factory(kTRUE); \ 00093 gGlobalMutex->UnLock(); \ 00094 } \ 00095 R__LOCKGUARD(mutex) 00096 #else 00097 #define R__LOCKGUARD(mutex) if (mutex) { } 00098 #define R__LOCKGUARD2(mutex) if (mutex) { } 00099 #endif 00100 00101 #endif