Logo ROOT   6.12/07
Reference Guide
TVirtualRWMutex.h
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Philippe Canal, 2017
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TVirtualRWMutex
13 #define ROOT_TVirtualRWMutex
14 
15 
16 //////////////////////////////////////////////////////////////////////////
17 // //
18 // TVirtualRWMutex //
19 // //
20 // This class implements a read-write mutex interface. The actual work //
21 // is done via TRWSpinLock which is available as soon as the thread //
22 // library is loaded. //
23 // //
24 //////////////////////////////////////////////////////////////////////////
25 
26 #include "TVirtualMutex.h"
27 
28 
29 namespace ROOT {
30 
32 
33 // Global mutex set in TThread::Init
34 // Use either R__READ_LOCKGUARD(ROOT::gCoreMutex);
35 // or R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
37 
39 
40 public:
41  // The following are opaque type and are never really declared
42  // The specific implementation of TInterpreter will cast the
43  // value of pointer to this types to the correct type (possibly
44  // distinct from these)
45  class Hint_t;
46 
47  /// \class State
48  /// Earlier lock state as returned by `GetState()` that can be passed to
49  /// `Restore()`
50  struct State {
51  virtual ~State(); // implemented in TVirtualMutex.cxx
52  };
53 
54  /// \class StateDelta
55  /// State as returned by `GetStateDelta()` that can be passed to
56  /// `Restore()`
57  struct StateDelta {
58  virtual ~StateDelta(); // implemented in TVirtualMutex.cxx
59  };
60 
61  virtual Hint_t *ReadLock() = 0;
62  virtual void ReadUnLock(Hint_t *) = 0;
63  virtual Hint_t *WriteLock() = 0;
64  virtual void WriteUnLock(Hint_t *) = 0;
65 
66  Int_t Lock() override { WriteLock(); return 1; }
67  Int_t TryLock() override { WriteLock(); return 1; }
68  Int_t UnLock() override { WriteUnLock(nullptr); return 1; }
69  Int_t CleanUp() override { WriteUnLock(nullptr); return 1; }
70 
71  virtual std::unique_ptr<State> GetStateBefore() = 0;
72  virtual std::unique_ptr<StateDelta> Rewind(const State& earlierState) = 0;
73  virtual void Apply(std::unique_ptr<StateDelta> &&delta) = 0;
74 
75  TVirtualRWMutex *Factory(Bool_t /*recursive*/ = kFALSE) override = 0;
76 
77  ClassDefOverride(TVirtualRWMutex, 0) // Virtual mutex lock class
78 };
79 
80 //////////////////////////////////////////////////////////////////////////
81 // //
82 // TReadLockGuard //
83 // //
84 // This class provides RW mutex resource management in a guaranteed and //
85 // exception safe way. Use like this: //
86 // { //
87 // TReadLockGuard guard(mutex); //
88 // ... // read something //
89 // } //
90 // when guard goes out of scope the mutex is unlocked in the TLockGuard //
91 // destructor. The exception mechanism takes care of calling the dtors //
92 // of local objects so it is exception safe. //
93 // //
94 //////////////////////////////////////////////////////////////////////////
95 
97 
98 private:
100  TVirtualRWMutex::Hint_t *fHint;
101 
102  TReadLockGuard(const TReadLockGuard&) = delete;
103  TReadLockGuard& operator=(const TReadLockGuard&) = delete;
104 
105 public:
106  TReadLockGuard(TVirtualRWMutex *mutex) : fMutex(mutex), fHint(nullptr) {
107  if (fMutex) fHint = fMutex->ReadLock();
108  }
109 
110  ~TReadLockGuard() { if (fMutex) fMutex->ReadUnLock(fHint); }
111 
112  ClassDefNV(TReadLockGuard,0) // Exception safe read locking/unlocking of mutex
113 };
114 
116 
117 private:
119  TVirtualRWMutex::Hint_t *fHint;
120 
121  TWriteLockGuard(const TWriteLockGuard&) = delete;
122  TWriteLockGuard& operator=(const TWriteLockGuard&) = delete;
123 
124 public:
125  TWriteLockGuard(TVirtualRWMutex *mutex) : fMutex(mutex), fHint(nullptr) {
126  if (fMutex) fHint = fMutex->WriteLock();
127  }
128 
129  ~TWriteLockGuard() { if (fMutex) fMutex->WriteUnLock(fHint); }
130 
131  ClassDefNV(TWriteLockGuard,0) // Exception safe read locking/unlocking of mutex
132 };
133 
134 } // namespace ROOT.
135 
136 // Zero overhead macros in case not compiled with thread support
137 #if defined (_REENTRANT) || defined (WIN32)
138 
139 #define R__READ_LOCKGUARD(mutex) ::ROOT::TReadLockGuard _R__UNIQUE_(R__readguard)(mutex)
140 #define R__READ_LOCKGUARD_NAMED(name,mutex) ::ROOT::TReadLockGuard _NAME2_(R__readguard,name)(mutex)
141 
142 #define R__WRITE_LOCKGUARD(mutex) ::ROOT::TWriteLockGuard _R__UNIQUE_(R__readguard)(mutex)
143 #define R__WRITE_LOCKGUARD_NAMED(name,mutex) ::ROOT::TWriteLockGuard _NAME2_(R__readguard,name)(mutex)
144 
145 #else
146 
147 #define R__READ_LOCKGUARD(mutex) (void)mutex
148 #define R__READ_LOCKGUARD_NAMED(name,mutex) (void)mutex
149 
150 #define R__WRITE_LOCKGUARD(mutex) (void)mutex
151 #define R__WRITE_LOCKGUARD_NAMED(name,mutex) (void)mutex
152 
153 #endif
154 
155 
156 #endif
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
virtual void ReadUnLock(Hint_t *)=0
virtual void WriteUnLock(Hint_t *)=0
This class implements a mutex interface.
Definition: TVirtualMutex.h:34
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TVirtualRWMutex::Hint_t * fHint
R__EXTERN TVirtualRWMutex * gCoreMutex
TWriteLockGuard(TVirtualRWMutex *mutex)
virtual Hint_t * WriteLock()=0
Int_t Lock() override
Int_t TryLock() override
#define ClassDefNV(name, id)
Definition: Rtypes.h:328
virtual std::unique_ptr< State > GetStateBefore()=0
State as returned by GetStateDelta() that can be passed to Restore()
const Bool_t kFALSE
Definition: RtypesCore.h:88
TVirtualRWMutex::Hint_t * fHint
virtual Hint_t * ReadLock()=0
Int_t UnLock() override
Int_t CleanUp() override
Earlier lock state as returned by GetState() that can be passed to Restore()
Binding & operator=(OUT(*fun)(void))
#define R__EXTERN
Definition: DllImport.h:27
#define ClassDefOverride(name, id)
Definition: Rtypes.h:324
TVirtualRWMutex * Factory(Bool_t=kFALSE) override=0
TVirtualRWMutex *const fMutex
TVirtualRWMutex *const fMutex
TReadLockGuard(TVirtualRWMutex *mutex)