Skip to content

Commit

Permalink
Fix #7093: race condition tripping TEnum::GetEnum
Browse files Browse the repository at this point in the history
  • Loading branch information
pcanal committed Feb 24, 2021
1 parent ca16633 commit cbfd8e4
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
8 changes: 5 additions & 3 deletions core/meta/src/TEnum.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
return en;
}

// Lock need for gROOT->GetListOfClasses() and the later update/modification to
// the autoparsing state.
R__LOCKGUARD(gInterpreterMutex);

if (auto tClassScope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
// If this is a class, load only if the user allowed interpreter lookup
// If this is a namespace and the user did not allow for interpreter lookup, load but before disable
Expand Down Expand Up @@ -236,6 +234,10 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
return nullptr;
}

// Keep the state consistent. I particular prevent change in the state of AutoLoading and AutoParsing allowance
// and gROOT->GetListOfClasses() and the later update/modification to the autoparsing state.
R__READ_LOCKGUARD(ROOT::gCoreMutex);

if (lastPos != enumName) {
// We have a scope
// All of this C gymnastic is to avoid allocations on the heap (see TClingLookupHelper__ExistingTypeCheck)
Expand Down
5 changes: 4 additions & 1 deletion core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6028,6 +6028,9 @@ Int_t TCling::DeepAutoLoadImpl(const char *cls)

Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
{
// Prevent update to IsClassAutoloading between our check and our actions.
R__READ_LOCKGUARD(ROOT::gCoreMutex);

// TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
// rootcling (in *_rdict.pcm file generation) it is a no op.
// FIXME: We should avoid calling autoload when we know we are not supposed
Expand All @@ -6042,7 +6045,7 @@ Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)

assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");

R__LOCKGUARD(gInterpreterMutex);
R__WRITE_LOCKGUARD(ROOT::gCoreMutex);

if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
// The library is already loaded as the class's dictionary is known.
Expand Down

0 comments on commit cbfd8e4

Please sign in to comment.