Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/TVirtualMutex.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // @(#)root/base:$Id$
0002 // Author: Fons Rademakers   14/07/2002
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TVirtualMutex
0013 #define ROOT_TVirtualMutex
0014 
0015 
0016 //////////////////////////////////////////////////////////////////////////
0017 //                                                                      //
0018 // TVirtualMutex                                                        //
0019 //                                                                      //
0020 // This class implements a mutex interface. The actual work is done via //
0021 // TMutex which is available as soon as the thread library is loaded.   //
0022 //                                                                      //
0023 //////////////////////////////////////////////////////////////////////////
0024 
0025 #include "Rtypes.h"
0026 
0027 class TVirtualMutex;
0028 
0029 // Global mutex set in TThread::Init
0030 R__EXTERN TVirtualMutex *gGlobalMutex;
0031 
0032 class TVirtualMutex {
0033 
0034 public:
0035    TVirtualMutex(Bool_t /* recursive */ = kFALSE) { }
0036    virtual ~TVirtualMutex() { }
0037 
0038    virtual Int_t Lock() = 0;
0039    virtual Int_t TryLock() = 0;
0040    virtual Int_t UnLock() = 0;
0041    virtual Int_t CleanUp() = 0;
0042    Int_t Acquire() { return Lock(); }
0043    Int_t Release() { return UnLock(); }
0044 
0045    virtual TVirtualMutex *Factory(Bool_t /*recursive*/ = kFALSE) = 0;
0046 
0047    ClassDef(TVirtualMutex, 0)  // Virtual mutex lock class
0048 };
0049 
0050 
0051 //////////////////////////////////////////////////////////////////////////
0052 //                                                                      //
0053 // TLockGuard                                                           //
0054 //                                                                      //
0055 // This class provides mutex resource management in a guaranteed and    //
0056 // exception safe way. Use like this:                                   //
0057 // {                                                                    //
0058 //    TLockGuard guard(mutex);                                          //
0059 //    ... // do something                                               //
0060 // }                                                                    //
0061 // where mutex is a pointer to a TMutex object.                         //
0062 // When guard goes out of scope the mutex is unlocked in the TLockGuard //
0063 // destructor. The exception mechanism takes care of calling the dtors  //
0064 // of local objects so it is exception safe.                            //
0065 // In contrast to std::lock_guard, TLockGuard constructor expects a     //
0066 // pointer, not the mutex object itself.                                //
0067 //                                                                      //
0068 //////////////////////////////////////////////////////////////////////////
0069 
0070 class TLockGuard {
0071 
0072 private:
0073    TVirtualMutex *fMutex{nullptr};
0074 
0075    TLockGuard(const TLockGuard&) = delete;
0076    TLockGuard& operator=(const TLockGuard&) = delete;
0077 
0078 public:
0079    TLockGuard(TVirtualMutex *mutex)
0080      : fMutex(mutex) { if (fMutex) fMutex->Lock(); }
0081    Int_t UnLock() {
0082       if (!fMutex) return 0;
0083       auto tmp = fMutex;
0084       fMutex = nullptr;
0085       return tmp->UnLock();
0086    }
0087    ~TLockGuard() { if (fMutex) fMutex->UnLock(); }
0088 
0089    ClassDefNV(TLockGuard,0)  // Exception safe locking/unlocking of mutex
0090 };
0091 
0092 // Use with a trailing semicolon and pass a pointer as argument, e.g.:
0093 // TMutex m; R__LOCKGUARD(&m);
0094 
0095 #define R__LOCKGUARD(mutex) TLockGuard _R__UNIQUE_(R__guard)(mutex)
0096 #define R__LOCKGUARD2(mutex)                             \
0097    if (gGlobalMutex && !mutex) {                         \
0098       gGlobalMutex->Lock();                              \
0099       if (!mutex)                                        \
0100          mutex = gGlobalMutex->Factory(kTRUE);           \
0101       gGlobalMutex->UnLock();                            \
0102    }                                                     \
0103    R__LOCKGUARD(mutex)
0104 #define R__LOCKGUARD_NAMED(name,mutex) TLockGuard _NAME2_(R__guard,name)(mutex)
0105 #define R__LOCKGUARD_UNLOCK(name) _NAME2_(R__guard,name).UnLock()
0106 
0107 #ifdef R__USE_IMT
0108 #define R__LOCKGUARD_IMT(mutex)  R__LOCKGUARD(ROOT::Internal::IsParBranchProcessingEnabled() ? mutex : nullptr)
0109 #define R__LOCKGUARD_IMT2(mutex)                                                   \
0110    if (gGlobalMutex && !mutex && ROOT::Internal::IsParBranchProcessingEnabled()) { \
0111       gGlobalMutex->Lock();                                                        \
0112       if (!mutex)                                                                  \
0113          mutex = gGlobalMutex->Factory(kTRUE);                                     \
0114       gGlobalMutex->UnLock();                                                      \
0115    }                                                                               \
0116    R__LOCKGUARD_IMT(mutex)
0117 #else
0118 #define R__LOCKGUARD_IMT(mutex)  { }
0119 #define R__LOCKGUARD_IMT2(mutex) { }
0120 #endif
0121 
0122 #endif