-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,24 +184,96 @@ void TReentrantRWLock<MutexT, RecurseCountsT>::WriteUnLock() | |
namespace { | ||
template <typename MutexT, typename RecurseCountsT> | ||
struct TReentrantRWLockState: public TVirtualMutex::State { | ||
RecurseCountsT fRecurseCounts; | ||
int fReadersCount = 0; | ||
size_t fWriteRecurse = 0; | ||
bool fIsWriter = false; | ||
}; | ||
} | ||
|
||
template <typename MutexT, typename RecurseCountsT> | ||
std::unique_ptr<TVirtualMutex::State> TReentrantRWLock<MutexT, RecurseCountsT>::Reset() | ||
{ | ||
std::unique_ptr<TReentrantRWLockState<MutexT, RecurseCountsT>> pState; | ||
using State_t = TReentrantRWLockState<MutexT, RecurseCountsT>; | ||
|
||
std::unique_ptr<State_t> pState(new State_t); | ||
auto local = fRecurseCounts.GetLocal(); | ||
|
||
size_t readerCount; | ||
{ | ||
std::unique_lock<MutexT> lock(fMutex); | ||
readerCount = fRecurseCounts.GetLocalReadersCount(local); | ||
} | ||
|
||
pState->fReadersCount = readerCount; | ||
|
||
if (fWriter && !fRecurseCounts.IsNotCurrentWriter(local)) { | ||
|
||
// We are holding the write lock. | ||
pState->fIsWriter = true; | ||
pState->fWriteRecurse = fRecurseCounts.fWriteRecurse; | ||
|
||
// Now set the lock (and potential read locks) for immediate release. | ||
fReaders -= readerCount; | ||
fRecurseCounts.fWriteRecurse = 1; | ||
// insertion in the reader count can only happen during a ReadLock | ||
// which can not execute until we release the write lock, so no | ||
// need to take the local mutex here. | ||
fRecurseCounts.ResetReadCount(local, 0); | ||
|
||
// Release this thread's write lock | ||
WriteUnLock(); | ||
} else if (readerCount) { | ||
// Now set the lock for release. | ||
{ | ||
std::unique_lock<MutexT> lock(fMutex); | ||
fReaders -= (readerCount-1); | ||
fRecurseCounts.ResetReadCount(local, 1); | ||
} | ||
|
||
// Release this thread's reader lock(s) | ||
ReadUnLock(); | ||
} | ||
|
||
// Do something. | ||
::Fatal("Reset()", "Not implemented, contact pcanal@fnal.gov"); | ||
//::Fatal("Reset()", "Not implemented, contact pcanal@fnal.gov"); | ||
return std::move(pState); | ||
} | ||
|
||
template <typename MutexT, typename RecurseCountsT> | ||
void TReentrantRWLock<MutexT, RecurseCountsT>::Restore(std::unique_ptr<TVirtualMutex::State> &&) | ||
void TReentrantRWLock<MutexT, RecurseCountsT>::Restore(std::unique_ptr<TVirtualMutex::State> &&state) | ||
{ | ||
TReentrantRWLockState<MutexT, RecurseCountsT> *pState = dynamic_cast<TReentrantRWLockState<MutexT, RecurseCountsT> *>(state.get()); | ||
if (!pState) { | ||
if (state) { | ||
SysError("Restore", "LOGIC ERROR - invalid state object!"); | ||
return; | ||
} | ||
// No state, do nothing. | ||
return; | ||
} | ||
|
||
if (pState->fIsWriter) { | ||
WriteLock(); | ||
// Now that we go the lock, fix up the recursion count. | ||
std::unique_lock<MutexT> lock(fMutex); | ||
fRecurseCounts.fWriteRecurse = pState->fWriteRecurse; | ||
auto local = fRecurseCounts.GetLocal(); | ||
fRecurseCounts.ResetReadCount(local, pState->fReadersCount); | ||
fReaders += pState->fReadersCount; | ||
} else { | ||
ReadLock(); | ||
// Now that we go the read lock, fix up the local recursion count. | ||
assert( pState->fReadersCount >= 1 ); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
pcanal
Author
Member
|
||
auto readerCount = pState->fReadersCount; | ||
|
||
std::unique_lock<MutexT> lock(fMutex); | ||
auto local = fRecurseCounts.GetLocal(); | ||
fRecurseCounts.ResetReadCount(local, readerCount); | ||
fReaders += readerCount - 1; | ||
} | ||
|
||
// Do something. | ||
::Fatal("Restore()", "Not implemented, contact pcanal@fnal.gov"); | ||
//::Fatal("Restore()", "Not implemented, contact pcanal@fnal.gov"); | ||
} | ||
|
||
namespace ROOT { | ||
|
@pcanal
Are you sure about this condition?
I have a code which fails at this place when I invoking gROOT->ProcessLine().
It is qt5-based application and this call happens in TTimer handler - means when I call gSystem->ProcessEvents().
If I simply comment out this line - everything works for me.
May be I need to change some global configuration to make some global mute reentrant?