@@ -354,27 +354,20 @@ void TCling__PrintStackTrace() {
354354}
355355
356356// //////////////////////////////////////////////////////////////////////////////
357- // / Restore the interpreter lock.
357+ // / Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused .
358358
359- extern " C" void TCling__RestoreInterpreterMutex (void *state )
359+ extern " C" void TCling__RestoreInterpreterMutex (void *delta )
360360{
361- if (gInterpreterMutex && state) {
362- auto typedState = static_cast <TVirtualMutex::State *>(state);
363- std::unique_ptr<TVirtualMutex::State> uniqueP{typedState};
364- gInterpreterMutex ->Restore (std::move (uniqueP));
365- }
361+ ((TCling*)gCling )->ApplyToInterpreterMutex (delta);
366362}
367363
368364// //////////////////////////////////////////////////////////////////////////////
369- // / Completely reset the interpreter lock.
365+ // / Reset the interpreter lock to the state it had before interpreter-related
366+ // / calls happened.
370367
371368extern " C" void *TCling__ResetInterpreterMutex ()
372369{
373- if (gInterpreterMutex ) {
374- auto uniqueP = gInterpreterMutex ->Reset ();
375- return uniqueP.release ();
376- }
377- return nullptr ;
370+ return ((TCling*)gCling )->RewindInterpreterMutex ();
378371}
379372
380373// //////////////////////////////////////////////////////////////////////////////
@@ -2120,7 +2113,7 @@ Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
21202113 gInterpreterMutex = gGlobalMutex ->Factory (kTRUE );
21212114 gGlobalMutex ->UnLock ();
21222115 }
2123- R__LOCKGUARD (fLockProcessLine ? gInterpreterMutex : 0 );
2116+ R__LOCKGUARD_CLING (fLockProcessLine ? gInterpreterMutex : 0 );
21242117 gROOT ->SetLineIsProcessing ();
21252118
21262119 struct InterpreterFlagsRAII {
@@ -2683,7 +2676,7 @@ void TCling::ClearStack()
26832676
26842677bool TCling::Declare (const char * code)
26852678{
2686- R__LOCKGUARD (gInterpreterMutex );
2679+ R__LOCKGUARD_CLING (gInterpreterMutex );
26872680
26882681 int oldload = SetClassAutoloading (0 );
26892682 SuspendAutoParsing autoParseRaii (this );
@@ -3000,7 +2993,7 @@ Int_t TCling::Load(const char* filename, Bool_t system)
30002993 }
30012994
30022995 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3003- R__LOCKGUARD (gInterpreterMutex );
2996+ R__LOCKGUARD_CLING (gInterpreterMutex );
30042997 cling::DynamicLibraryManager* DLM = fInterpreter ->getDynamicLibraryManager ();
30052998 std::string canonLib = DLM->lookupLibrary (filename);
30062999 cling::DynamicLibraryManager::LoadLibResult res
@@ -3051,7 +3044,7 @@ Long_t TCling::ProcessLineAsynch(const char* line, EErrorCode* error)
30513044
30523045Long_t TCling::ProcessLineSynch (const char * line, EErrorCode* error)
30533046{
3054- R__LOCKGUARD (fLockProcessLine ? gInterpreterMutex : 0 );
3047+ R__LOCKGUARD_CLING (fLockProcessLine ? gInterpreterMutex : 0 );
30553048 if (gApplication ) {
30563049 if (gApplication ->IsCmdThread ()) {
30573050 return ProcessLine (line, error);
@@ -3079,7 +3072,7 @@ Long_t TCling::Calc(const char* line, EErrorCode* error)
30793072 gROOT ->SetLineIsProcessing ();
30803073 }
30813074#endif // R__WIN32
3082- R__LOCKGUARD (gInterpreterMutex );
3075+ R__LOCKGUARD_CLING (gInterpreterMutex );
30833076 if (error) {
30843077 *error = TInterpreter::kNoError ;
30853078 }
@@ -4565,7 +4558,7 @@ void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_
45654558
45664559void TCling::Execute (const char * function, const char * params, int * error)
45674560{
4568- R__LOCKGUARD (gInterpreterMutex );
4561+ R__LOCKGUARD_CLING (gInterpreterMutex );
45694562 if (error) {
45704563 *error = TInterpreter::kNoError ;
45714564 }
@@ -4590,7 +4583,7 @@ void TCling::Execute(const char* function, const char* params, int* error)
45904583void TCling::Execute (TObject* obj, TClass* cl, const char * method,
45914584 const char * params, Bool_t objectIsConst, int * error)
45924585{
4593- R__LOCKGUARD (gInterpreterMutex );
4586+ R__LOCKGUARD_CLING (gInterpreterMutex );
45944587 if (error) {
45954588 *error = TInterpreter::kNoError ;
45964589 }
@@ -4693,7 +4686,7 @@ void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
46934686 }
46944687
46954688 // And now execute it.
4696- R__LOCKGUARD (gInterpreterMutex );
4689+ R__LOCKGUARD_CLING (gInterpreterMutex );
46974690 if (error) {
46984691 *error = TInterpreter::kNoError ;
46994692 }
@@ -4735,7 +4728,7 @@ void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
47354728
47364729Long_t TCling::ExecuteMacro (const char * filename, EErrorCode* error)
47374730{
4738- R__LOCKGUARD (fLockProcessLine ? gInterpreterMutex : 0 );
4731+ R__LOCKGUARD_CLING (fLockProcessLine ? gInterpreterMutex : 0 );
47394732 fCurExecutingMacros .push_back (filename);
47404733 Long_t result = TApplication::ExecuteFile (filename, (int *)error);
47414734 fCurExecutingMacros .pop_back ();
@@ -8453,3 +8446,66 @@ const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
84538446 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
84548447 return TClinginfo->Title ();
84558448}
8449+
8450+ // //////////////////////////////////////////////////////////////////////////////
8451+
8452+ void TCling::SnapshotMutexState (ROOT::TVirtualRWMutex* mtx)
8453+ {
8454+ if (!fInitialMutex .back ()) {
8455+ if (fInitialMutex .back ().fRecurseCount ) {
8456+ Error (" SnapshotMutexState" , " fRecurseCount != 0 even though initial mutex state is unset!" );
8457+ }
8458+ fInitialMutex .back ().fState = mtx->GetStateBefore ();
8459+ }
8460+ // We will "forget" this lock once we backed out of all interpreter frames.
8461+ // Here we are entering one, so ++.
8462+ ++fInitialMutex .back ().fRecurseCount ;
8463+ }
8464+
8465+ // //////////////////////////////////////////////////////////////////////////////
8466+
8467+ void TCling::ForgetMutexState ()
8468+ {
8469+ if (!fInitialMutex .back ())
8470+ return ;
8471+ if (fInitialMutex .back ().fRecurseCount == 0 ) {
8472+ Error (" ForgetMutexState" , " mutex state's recurse count already 0!" );
8473+ }
8474+ else if (--fInitialMutex .back ().fRecurseCount == 0 ) {
8475+ // We have returned from all interpreter frames. Reset the initial lock state.
8476+ fInitialMutex .back ().fState .reset ();
8477+ }
8478+ }
8479+
8480+ // //////////////////////////////////////////////////////////////////////////////
8481+ // / Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
8482+
8483+ void TCling::ApplyToInterpreterMutex (void *delta)
8484+ {
8485+ R__ASSERT (!fInitialMutex .empty () && " Inconsistent state of fInitialMutex!" );
8486+ if (gInterpreterMutex ) {
8487+ if (delta) {
8488+ auto typedDelta = static_cast <TVirtualRWMutex::StateDelta *>(delta);
8489+ std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP{typedDelta};
8490+ gCoreMutex ->Apply (std::move (uniqueP));
8491+ }
8492+ }
8493+ fInitialMutex .pop_back ();
8494+ }
8495+
8496+ // //////////////////////////////////////////////////////////////////////////////
8497+ // / Reset the interpreter lock to the state it had before interpreter-related
8498+ // / calls happened.
8499+
8500+ void *TCling::RewindInterpreterMutex ()
8501+ {
8502+ if (fInitialMutex .back ()) {
8503+ std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP = gCoreMutex ->Rewind (*fInitialMutex .back ().fState );
8504+ // Need to start a new recurse count.
8505+ fInitialMutex .emplace_back ();
8506+ return uniqueP.release ();
8507+ }
8508+ // Need to start a new recurse count.
8509+ fInitialMutex .emplace_back ();
8510+ return nullptr ;
8511+ }
0 commit comments