diff --git a/core/base/inc/TVirtualRWMutex.h b/core/base/inc/TVirtualRWMutex.h index abf3eecb3b9eb2eaa3ba723057964e378efe1503..bc6000866ce6d25833e0ee437851983f97aa2ba5 100644 --- a/core/base/inc/TVirtualRWMutex.h +++ b/core/base/inc/TVirtualRWMutex.h @@ -44,6 +44,20 @@ public: // distinct from these) class Hint_t; + /// \class State + /// Earlier lock state as returned by `GetState()` that can be passed to + /// `Restore()` + struct State { + virtual ~State(); // implemented in TVirtualMutex.cxx + }; + + /// \class StateDelta + /// State as returned by `GetStateDelta()` that can be passed to + /// `Restore()` + struct StateDelta { + virtual ~StateDelta(); // implemented in TVirtualMutex.cxx + }; + virtual Hint_t *ReadLock() = 0; virtual void ReadUnLock(Hint_t *) = 0; virtual Hint_t *WriteLock() = 0; @@ -54,6 +68,10 @@ public: Int_t UnLock() override { WriteUnLock(nullptr); return 1; } Int_t CleanUp() override { WriteUnLock(nullptr); return 1; } + virtual std::unique_ptr<State> GetState() const = 0; + virtual std::unique_ptr<StateDelta> Rewind(const State& earlierState) = 0; + virtual void Apply(std::unique_ptr<StateDelta> &&delta) = 0; + TVirtualRWMutex *Factory(Bool_t /*recursive*/ = kFALSE) override = 0; ClassDefOverride(TVirtualRWMutex, 0) // Virtual mutex lock class diff --git a/core/base/src/TVirtualMutex.cxx b/core/base/src/TVirtualMutex.cxx index 46e14f73a046a69d760d1274933fdb88286177bb..1e7a112aeb172c4648aecf22fd1e95c94c29e1bc 100644 --- a/core/base/src/TVirtualMutex.cxx +++ b/core/base/src/TVirtualMutex.cxx @@ -33,6 +33,7 @@ of local objects so it is exception safe. */ #include "TVirtualMutex.h" +#include "TVirtualRWMutex.h" ClassImp(TVirtualMutex); ClassImp(TLockGuard); @@ -42,3 +43,7 @@ ClassImp(TLockGuard); // concept gGlobalMutex must be used in TStorage to prevent // lockup of the system (see TMutex::Factory) TVirtualMutex *gGlobalMutex = 0; + +// From TVirtualRWMutex.h: +ROOT::TVirtualRWMutex::State::~State() = default; +ROOT::TVirtualRWMutex::StateDelta::~StateDelta() = default; \ No newline at end of file diff --git a/core/thread/src/TRWMutexImp.cxx b/core/thread/src/TRWMutexImp.cxx index 3607796ea1211461ee7c5826f4148d9eb50a5180..91234d2aa0edee8306aa435dfa5370b3d1fb79e4 100644 --- a/core/thread/src/TRWMutexImp.cxx +++ b/core/thread/src/TRWMutexImp.cxx @@ -70,24 +70,37 @@ TVirtualRWMutex *TRWMutexImp<MutexT, RecurseCountsT>::Factory(Bool_t /*recursive } //////////////////////////////////////////////////////////////////////////////// -/// Reset the mutex state to unlocked. The state before resetting to unlocked is -/// returned and can be passed to `Restore()` later on. This function must only -/// be called while the mutex is locked. +/// Restore the mutex state to the state represented by `state`. This function +/// must only be called while the mutex is locked. Returns the DeltaState +/// between now and the rewind point, such that the difference can be re-applied +/// using `Apply()`. template <typename MutexT, typename RecurseCountsT> -std::unique_ptr<TVirtualMutex::State> TRWMutexImp<MutexT, RecurseCountsT>::Reset() +std::unique_ptr<TVirtualRWMutex::StateDelta> +TRWMutexImp<MutexT, RecurseCountsT>::Rewind(const TVirtualRWMutex::State &earlierState) { - return fMutexImp.Reset(); + return fMutexImp.Rewind(earlierState); } //////////////////////////////////////////////////////////////////////////////// -/// Restore the mutex state to the state pointed to by `state`. This function -/// must only be called while the mutex is unlocked. +/// Apply the mutex state delta. This function must only be called while the +/// mutex is locked. template <typename MutexT, typename RecurseCountsT> -void TRWMutexImp<MutexT, RecurseCountsT>::Restore(std::unique_ptr<TVirtualMutex::State> &&state) +void TRWMutexImp<MutexT, RecurseCountsT>::Apply(std::unique_ptr<TVirtualRWMutex::StateDelta> &&delta) { - fMutexImp.Restore(std::move(state)); + fMutexImp.Apply(std::move(delta)); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Get the mutex state. This function must only be called while the mutex is +/// locked. + +template <typename MutexT, typename RecurseCountsT> +std::unique_ptr<TVirtualRWMutex::State> +TRWMutexImp<MutexT, RecurseCountsT>::GetState() const +{ + return fMutexImp.GetState(); } template class TRWMutexImp<TMutex>; diff --git a/core/thread/src/TRWMutexImp.h b/core/thread/src/TRWMutexImp.h index bd77c69e3956736db0c759113a58079a02edbc04..5b9dd11e7e58656067dfcbd398fc9d357ff0328e 100644 --- a/core/thread/src/TRWMutexImp.h +++ b/core/thread/src/TRWMutexImp.h @@ -29,8 +29,9 @@ public: void WriteUnLock(Hint_t *) override; TVirtualRWMutex *Factory(Bool_t /*recursive*/ = kFALSE) override; - std::unique_ptr<TVirtualMutex::State> Reset() override; - void Restore(std::unique_ptr<TVirtualMutex::State> &&) override; + std::unique_ptr<State> GetState() const override; + std::unique_ptr<StateDelta> Rewind(const State &earlierState) override; + void Apply(std::unique_ptr<StateDelta> &&delta) override; ClassDefInlineOverride(TRWMutexImp,0) // Concrete RW mutex lock class };