13#ifndef ROOT_TReentrantRWLock 
   14#define ROOT_TReentrantRWLock 
   21#include <condition_variable> 
   23#include <unordered_map> 
   26#include "tbb/enumerable_thread_specific.h" 
   32   using Hint_t = TVirtualRWMutex::Hint_t;
 
   50      ++(
local->fReadersCount);
 
   51      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&(
local->fReadersCount));
 
 
   54   template <
typename MutexT>
 
   60      --(
local->fReadersCount);
 
   61      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&(
local->fReadersCount));
 
 
   64   template <
typename MutexT>
 
   82      local->fIsWriter = 
true;
 
 
 
   93   using Hint_t = TVirtualRWMutex::Hint_t;
 
  107      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&count);
 
 
  110   template <
typename MutexT>
 
  113      std::unique_lock<MutexT> lock(mutex);
 
 
  120      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&count);
 
 
  123   template <
typename MutexT>
 
  126      std::unique_lock<MutexT> lock(mutex);
 
 
 
  157   using Hint_t = TVirtualRWMutex::Hint_t;
 
  160      size_t fReadersCount = 0;
 
  161      bool fIsWriter = 
false;
 
  163   tbb::enumerable_thread_specific<LocalCounts> 
fLocalCounts;
 
  164   size_t fWriteRecurse = 0; 
 
  166   using local_t = LocalCounts *;
 
  170   Hint_t *IncrementReadCount(local_t &
local)
 
  172      ++(
local->fReadersCount);
 
  173      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&(
local->fReadersCount));
 
  176   template <
typename MutexT>
 
  177   Hint_t *IncrementReadCount(local_t &
local, 
MutexT &)
 
  179      return IncrementReadCount(
local);
 
  182   Hint_t *DecrementReadCount(local_t &
local)
 
  184      --(
local->fReadersCount);
 
  185      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&(
local->fReadersCount));
 
  188   template <
typename MutexT>
 
  189   Hint_t *DecrementReadCount(local_t &
local, 
MutexT &)
 
  191      return DecrementReadCount(
local);
 
  196   bool IsCurrentWriter(local_t &
local) { 
return local->fIsWriter; }
 
  197   bool IsNotCurrentWriter(local_t &
local) { 
return !
local->fIsWriter; }
 
  199   void SetIsWriter(local_t &
local)
 
  205      local->fIsWriter = 
true;
 
  208   void DecrementWriteCount() { --fWriteRecurse; }
 
  210   void ResetIsWriter(local_t &
local) { 
local->fIsWriter = 
false; }
 
  212   size_t &GetLocalReadersCount(local_t &
local) { 
return local->fReadersCount; }
 
  216   using Hint_t = TVirtualRWMutex::Hint_t;
 
  219      size_t fReadersCount = 0;
 
  220      bool fIsWriter = 
false;
 
  222   tbb::enumerable_thread_specific<LocalCounts, tbb::cache_aligned_allocator<LocalCounts>, tbb::ets_key_per_instance>
 
  224   size_t fWriteRecurse = 0; 
 
  226   using local_t = LocalCounts *;
 
  230   Hint_t *IncrementReadCount(local_t &
local)
 
  232      ++(
local->fReadersCount);
 
  233      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&(
local->fReadersCount));
 
  236   template <
typename MutexT>
 
  237   Hint_t *IncrementReadCount(local_t &
local, 
MutexT &)
 
  239      return IncrementReadCount(
local);
 
  242   Hint_t *DecrementReadCount(local_t &
local)
 
  244      --(
local->fReadersCount);
 
  245      return reinterpret_cast<TVirtualRWMutex::Hint_t *
>(&(
local->fReadersCount));
 
  248   template <
typename MutexT>
 
  249   Hint_t *DecrementReadCount(local_t &
local, 
MutexT &)
 
  251      return DecrementReadCount(
local);
 
  256   bool IsCurrentWriter(local_t &
local) { 
return local->fIsWriter; }
 
  257   bool IsNotCurrentWriter(local_t &
local) { 
return !
local->fIsWriter; }
 
  259   void SetIsWriter(local_t &
local)
 
  265      local->fIsWriter = 
true;
 
  268   void DecrementWriteCount() { --fWriteRecurse; }
 
  270   void ResetIsWriter(local_t &
local) { 
local->fIsWriter = 
false; }
 
  272   size_t &GetLocalReadersCount(local_t &
local) { 
return local->fReadersCount; }
 
  278template <
typename MutexT = ROOT::TSpinMutex, 
typename RecurseCountsT = Internal::RecurseCounts>
 
  306   TVirtualRWMutex::Hint_t *
ReadLock();
 
  313   void Apply(std::unique_ptr<StateDelta> &&delta);
 
 
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
std::condition_variable_any fCond
! RWlock internal condition variable
void WriteUnLock(TVirtualRWMutex::Hint_t *)
Release the lock in write mode.
TVirtualRWMutex::State State
std::atomic< int > fReaderReservation
! A reader wants access
std::unique_ptr< StateDelta > Rewind(const State &earlierState)
Rewind to an earlier mutex state, returning the delta.
TVirtualRWMutex::Hint_t * ReadLock()
Acquire the lock in read mode.
RecurseCountsT fRecurseCounts
! Trackers for re-entry in the lock by the same thread.
TVirtualRWMutex::Hint_t * WriteLock()
Acquire the lock in write mode.
std::atomic< bool > fWriter
! Is there a writer?
std::atomic< int > fReaders
! Number of readers
void ReadUnLock(TVirtualRWMutex::Hint_t *)
Release the lock in read mode.
void AssertReadCountLocIsFromCurrentThread(const size_t *presumedLocalReadersCount)
Assert that presumedLocalReadersCount really matches the local read count.
MutexT fMutex
! RWlock internal mutex
std::unique_ptr< State > GetStateBefore()
Get the lock state before the most recent write lock was taken.
TReentrantRWLock()
Regular constructor.
void Apply(std::unique_ptr< StateDelta > &&delta)
Re-apply a delta.
std::atomic< int > fWriterReservation
! A writer wants access
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Hint_t * DecrementReadCount(local_t &local)
size_t fWriteRecurse
! Number of re-entry in the lock by the same thread.
Hint_t * DecrementReadCount(local_t &local, MutexT &mutex)
bool IsNotCurrentWriter(local_t &local) const
std::unordered_map< std::thread::id, size_t > ReaderColl_t
bool IsCurrentWriter(local_t &local) const
void ResetIsWriter(local_t &)
std::thread::id fWriterThread
! Holder of the write lock
void DecrementWriteCount()
TVirtualRWMutex::Hint_t Hint_t
Hint_t * IncrementReadCount(local_t &local)
void ResetReadCount(local_t &local, int newvalue)
ReaderColl_t fReadersCount
! Set of reader thread ids
Hint_t * IncrementReadCount(local_t &local, MutexT &mutex)
size_t & GetLocalReadersCount(local_t &local)
void SetIsWriter(local_t &local)
bool IsCurrentWriter(local_t &local)
Hint_t * DecrementReadCount(local_t &local)
bool IsNotCurrentWriter(local_t &local)
Hint_t * IncrementReadCount(local_t &local, MutexT &)
void ResetReadCount(local_t &local, int newvalue)
TVirtualRWMutex::Hint_t Hint_t
void DecrementWriteCount()
void ResetIsWriter(local_t &local)
Hint_t * IncrementReadCount(local_t &local)
Hint_t * DecrementReadCount(local_t &local, MutexT &)
size_t & GetLocalReadersCount(local_t &local)
void SetIsWriter(local_t &local)
size_t fWriteRecurse
! Number of re-entry in the lock by the same thread.
State as returned by GetStateDelta() that can be passed to Restore()
Earlier lock state as returned by GetState() that can be passed to Restore()