Logo ROOT  
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#include <memory>
29
30namespace ROOT {
31
32class TVirtualRWMutex;
33
34// Global mutex set in TThread::Init
35// Use either R__READ_LOCKGUARD(ROOT::gCoreMutex);
36// or R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
38
40
41public:
42 // The following are opaque type and are never really declared
43 // The specific implementation of TInterpreter will cast the
44 // value of pointer to this types to the correct type (possibly
45 // distinct from these)
46 class Hint_t;
47
48 /// \class State
49 /// Earlier lock state as returned by `GetState()` that can be passed to
50 /// `Restore()`
51 struct State {
52 virtual ~State(); // implemented in TVirtualMutex.cxx
53 };
54
56 /// State of gCoreMutex when the first interpreter-related function was invoked.
57 std::unique_ptr<ROOT::TVirtualRWMutex::State> fState;
58
59 /// Interpreter-related functions will push the "entry" lock state to *this.
60 /// Recursive calls will do that, too - but we must only forget about the lock
61 /// state once this recursion count went to 0.
63
64 operator bool() const { return (bool)fState; }
65 };
66
67 /// \class StateDelta
68 /// State as returned by `GetStateDelta()` that can be passed to
69 /// `Restore()`
70 struct StateDelta {
71 virtual ~StateDelta(); // implemented in TVirtualMutex.cxx
72 };
73
74 virtual Hint_t *ReadLock() = 0;
75 virtual void ReadUnLock(Hint_t *) = 0;
76 virtual Hint_t *WriteLock() = 0;
77 virtual void WriteUnLock(Hint_t *) = 0;
78
79 Int_t Lock() override { WriteLock(); return 1; }
80 Int_t TryLock() override { WriteLock(); return 1; }
81 Int_t UnLock() override { WriteUnLock(nullptr); return 1; }
82 Int_t CleanUp() override { WriteUnLock(nullptr); return 1; }
83
84 virtual std::unique_ptr<State> GetStateBefore() = 0;
85 virtual std::unique_ptr<StateDelta> Rewind(const State& earlierState) = 0;
86 virtual void Apply(std::unique_ptr<StateDelta> &&delta) = 0;
87
88 TVirtualRWMutex *Factory(Bool_t /*recursive*/ = kFALSE) override = 0;
89
90 ClassDefOverride(TVirtualRWMutex, 0) // Virtual mutex lock class
91};
92
93//////////////////////////////////////////////////////////////////////////
94// //
95// TReadLockGuard //
96// //
97// This class provides RW mutex resource management in a guaranteed and //
98// exception safe way. Use like this: //
99// { //
100// TReadLockGuard guard(mutex); //
101// ... // read something //
102// } //
103// where mutex is a pointer to a TMutex object. //
104// When guard goes out of scope the mutex is unlocked in the TLockGuard //
105// destructor. The exception mechanism takes care of calling the dtors //
106// of local objects so it is exception safe. //
107// In contrast to std::lock_guard, TLockGuard constructor expects a //
108// pointer, not the mutex object itself. //
109// //
110//////////////////////////////////////////////////////////////////////////
111
113
114private:
116 TVirtualRWMutex::Hint_t *fHint;
117
120
121public:
122 TReadLockGuard(TVirtualRWMutex *mutex) : fMutex(mutex), fHint(nullptr) {
123 if (fMutex) fHint = fMutex->ReadLock();
124 }
125
127
128 ClassDefNV(TReadLockGuard,0) // Exception safe read locking/unlocking of mutex
129};
130
132
133private:
135 TVirtualRWMutex::Hint_t *fHint;
136
139
140public:
141 TWriteLockGuard(TVirtualRWMutex *mutex) : fMutex(mutex), fHint(nullptr) {
142 if (fMutex) fHint = fMutex->WriteLock();
143 }
144
146
147 ClassDefNV(TWriteLockGuard,0) // Exception safe read locking/unlocking of mutex
148};
149
150} // namespace ROOT.
151
152// Zero overhead macros in case not compiled with thread support (-pthread)
153// Use with a trailing semicolon and pass a pointer as argument, e.g.:
154// TMutex m; R__READ_LOCKGUARD(&m);
155// Warning: if program is compiled without pthread support, _REENTRANT will
156// be undefined and the macro has (silently) no effect, no locks are performed.
157#if defined (_REENTRANT) || defined (WIN32)
158
159#define R__READ_LOCKGUARD(mutex) ::ROOT::TReadLockGuard _R__UNIQUE_(R__readguard)(mutex)
160#define R__READ_LOCKGUARD_NAMED(name,mutex) ::ROOT::TReadLockGuard _NAME2_(R__readguard,name)(mutex)
161
162#define R__WRITE_LOCKGUARD(mutex) ::ROOT::TWriteLockGuard _R__UNIQUE_(R__readguard)(mutex)
163#define R__WRITE_LOCKGUARD_NAMED(name,mutex) ::ROOT::TWriteLockGuard _NAME2_(R__readguard,name)(mutex)
164
165#else
166//@todo: mutex is not checked to be of type TVirtualMutex*.
167#define R__READ_LOCKGUARD(mutex) (void)mutex
168#define R__READ_LOCKGUARD_NAMED(name,mutex) (void)mutex
169
170#define R__WRITE_LOCKGUARD(mutex) (void)mutex
171#define R__WRITE_LOCKGUARD_NAMED(name,mutex) (void)mutex
172
173#endif
174
175
176#endif
#define R__EXTERN
Definition: DllImport.h:27
const Bool_t kFALSE
Definition: RtypesCore.h:101
#define ClassDefNV(name, id)
Definition: Rtypes.h:343
#define ClassDefOverride(name, id)
Definition: Rtypes.h:339
TReadLockGuard(const TReadLockGuard &)=delete
TReadLockGuard & operator=(const TReadLockGuard &)=delete
TVirtualRWMutex *const fMutex
TReadLockGuard(TVirtualRWMutex *mutex)
TVirtualRWMutex::Hint_t * fHint
Int_t CleanUp() override
virtual void ReadUnLock(Hint_t *)=0
Int_t UnLock() override
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual Hint_t * WriteLock()=0
TVirtualRWMutex * Factory(Bool_t=kFALSE) override=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual Hint_t * ReadLock()=0
virtual std::unique_ptr< State > GetStateBefore()=0
Int_t TryLock() override
virtual void WriteUnLock(Hint_t *)=0
Int_t Lock() override
TWriteLockGuard(TVirtualRWMutex *mutex)
TWriteLockGuard & operator=(const TWriteLockGuard &)=delete
TVirtualRWMutex *const fMutex
TWriteLockGuard(const TWriteLockGuard &)=delete
TVirtualRWMutex::Hint_t * fHint
This class implements a mutex interface.
Definition: TVirtualMutex.h:32
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
R__EXTERN TVirtualRWMutex * gCoreMutex
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
State as returned by GetStateDelta() that can be passed to Restore()
Earlier lock state as returned by GetState() that can be passed to Restore()