Skip to content

Made calling TGenCollectionStreamer::Generate thread safe #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions io/io/inc/TGenCollectionProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#include "TCollectionProxyInfo.h"
#endif

#if __cplusplus >= 201103L
#include <atomic>
#endif
#include <typeinfo>
#include <string>
#include <map>
Expand Down Expand Up @@ -325,7 +328,11 @@ class TGenCollectionProxy
Feedfunc_t fFeed; // Container accessors: block feed
Collectfunc_t fCollect; // Method to collect objects from container
Method0 fCreateEnv; // Method to allocate an Environment holder.
#if __cplusplus >= 201103L
std::atomic<Value*> fValue; // Descriptor of the container value type
#else
Value* fValue; // Descriptor of the container value type
#endif
Value* fVal; // Descriptor of the Value_type
Value* fKey; // Descriptor of the key_type
EnvironBase_t*fEnv; // Address of the currently proxied object
Expand Down
4 changes: 2 additions & 2 deletions io/io/src/TEmulatedCollectionProxy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ TGenCollectionProxy *TEmulatedCollectionProxy::InitializeEx(Bool_t silent)
fValue = new Value(nam,silent);
fKey = new Value(inside[1],silent);
fVal = new Value(inside[2],silent);
if ( !fValue->IsValid() || !fKey->IsValid() || !fVal->IsValid() ) {
if ( !(*fValue).IsValid() || !fKey->IsValid() || !fVal->IsValid() ) {
return 0;
}
fPointers |= 0 != (fKey->fCase&G__BIT_ISPOINTER);
Expand All @@ -172,7 +172,7 @@ TGenCollectionProxy *TEmulatedCollectionProxy::InitializeEx(Bool_t silent)
default:
fValue = new Value(inside[1],silent);
fVal = new Value(*fValue);
if ( !fValue->IsValid() || !fVal->IsValid() ) {
if ( !(*fValue).IsValid() || !fVal->IsValid() ) {
return 0;
}
if ( 0 == fValDiff ) {
Expand Down
20 changes: 11 additions & 9 deletions io/io/src/TGenCollectionProxy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ TGenCollectionProxy::~TGenCollectionProxy()
clearVector(fProxyKept);
clearVector(fStaged);

if ( fValue ) delete fValue;
if ( fValue ) delete fValue.load();
if ( fVal ) delete fVal;
if ( fKey ) delete fKey;

Expand Down Expand Up @@ -693,7 +693,7 @@ TVirtualCollectionProxy* TGenCollectionProxy::Generate() const
return new TGenBitsetProxy(*this);
}
case TClassEdit::kVector: {
if (fValue->fKind == (EDataType)kBOOL_t) {
if ((*fValue).fKind == (EDataType)kBOOL_t) {
return new TGenVectorBoolProxy(*this);
} else {
return new TGenVectorProxy(*this);
Expand All @@ -718,7 +718,6 @@ TGenCollectionProxy *TGenCollectionProxy::Initialize(Bool_t silent) const
// Proxy initializer
TGenCollectionProxy* p = const_cast<TGenCollectionProxy*>(this);
if ( fValue ) return p;
const_cast<TGenCollectionProxy*>(this)->fProperties |= kIsInitialized;
return p->InitializeEx(silent);
}

Expand Down Expand Up @@ -786,6 +785,7 @@ TGenCollectionProxy *TGenCollectionProxy::InitializeEx(Bool_t silent)
int num = TClassEdit::GetSplit(cl->GetName(),inside,nested);
if ( num > 1 ) {
std::string nam;
Value* newfValue = fValue;
if ( inside[0].find("stdext::hash_") != std::string::npos )
inside[0].replace(3,10,"::");
if ( inside[0].find("__gnu_cxx::hash_") != std::string::npos )
Expand All @@ -807,7 +807,7 @@ TGenCollectionProxy *TGenCollectionProxy::InitializeEx(Bool_t silent)
case TClassEdit::kMultiMap:
nam = "pair<"+inside[1]+","+inside[2];
nam += (nam[nam.length()-1]=='>') ? " >" : ">";
fValue = R__CreateValue(nam, silent);
newfValue = R__CreateValue(nam, silent);

fVal = R__CreateValue(inside[2], silent);
fKey = R__CreateValue(inside[1], silent);
Expand All @@ -829,9 +829,9 @@ TGenCollectionProxy *TGenCollectionProxy::InitializeEx(Bool_t silent)
inside[1] = "bool";
// Intentional fall through
default:
fValue = R__CreateValue(inside[1], silent);
newfValue = R__CreateValue(inside[1], silent);

fVal = new Value(*fValue);
fVal = new Value(*newfValue);
if ( 0 == fValDiff ) {
fValDiff = fVal->fSize;
fValDiff += (slong - fValDiff%slong)%slong;
Expand All @@ -844,6 +844,8 @@ TGenCollectionProxy *TGenCollectionProxy::InitializeEx(Bool_t silent)
fProperties |= kNeedDelete;
}
fClass = cl;
//fValue must be set last since we use it to indicate that we are initialized
fValue = newfValue;
return this;
}
Fatal("TGenCollectionProxy","Components of %s not analysed!",cl->GetName());
Expand Down Expand Up @@ -908,7 +910,7 @@ TClass *TGenCollectionProxy::GetValueClass() const
// Return a pointer to the TClass representing the content.

if (!fValue) Initialize(kFALSE);
return fValue ? fValue->fType.GetClass() : 0;
return fValue ? (*fValue).fType.GetClass() : 0;
}

//______________________________________________________________________________
Expand All @@ -917,7 +919,7 @@ void TGenCollectionProxy::SetValueClass(TClass *new_Value_type)
// Set pointer to the TClass representing the content.

if (!fValue) Initialize(kFALSE);
fValue->fType = new_Value_type;
(*fValue).fType = new_Value_type;
}

//______________________________________________________________________________
Expand All @@ -926,7 +928,7 @@ EDataType TGenCollectionProxy::GetType() const
// If the content is a simple numerical value, return its type (see TDataType)

if ( !fValue ) Initialize(kFALSE);
return fValue->fKind;
return (*fValue).fKind;
}

//______________________________________________________________________________
Expand Down
2 changes: 1 addition & 1 deletion io/io/src/TGenCollectionStreamer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ TGenCollectionStreamer::~TGenCollectionStreamer()
TVirtualCollectionProxy* TGenCollectionStreamer::Generate() const
{
// Virtual copy constructor.
if (!fClass) Initialize(kFALSE);
if (!fValue) Initialize(kFALSE);
return new TGenCollectionStreamer(*this);
}

Expand Down