Skip to content

Commit

Permalink
Protect access to IsCompiled
Browse files Browse the repository at this point in the history
Make sure that IsCompiled is only set once the TStreamerInfo is
actually compiled. Also, make sure to lock and then check the value
again to avoid two threads from recompiling the same object.
  • Loading branch information
Dr15Jones committed Oct 14, 2014
1 parent 849965b commit 83e9a81
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
20 changes: 14 additions & 6 deletions io/io/src/TBufferFile.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3684,10 +3684,14 @@ Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, Int_t versio
return 0;
}
} else if (!sinfo->IsCompiled()) {
// Streamer info has not been compiled, but exists.
// Therefore it was read in from a file and we have to do schema evolution.
const_cast<TClass*>(cl)->BuildRealData(pointer);
sinfo->BuildOld();
//See if another thread beat us to it
R__LOCKGUARD(gCINTMutex);
if(!sinfo->IsCompiled()) {
// Streamer info has not been compiled, but exists.
// Therefore it was read in from a file and we have to do schema evolution.
const_cast<TClass*>(cl)->BuildRealData(pointer);
sinfo->BuildOld();
}
}
}

Expand Down Expand Up @@ -3830,8 +3834,12 @@ Int_t TBufferFile::WriteClassBuffer(const TClass *cl, void *pointer)
sinfo->Build();
}
} else if (!sinfo->IsCompiled()) {
const_cast<TClass*>(cl)->BuildRealData(pointer);
sinfo->BuildOld();
//see if another thread beat us to it
R__LOCKGUARD(gCINTMutex);
if(!sinfo->IsCompiled()) {
const_cast<TClass*>(cl)->BuildRealData(pointer);
sinfo->BuildOld();
}
}

//write the class version number and reserve space for the byte count
Expand Down
11 changes: 10 additions & 1 deletion io/io/src/TStreamerInfoActions.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,15 @@ static TConfiguredAction GetCollectionWriteAction(TVirtualStreamerInfo *info, TS
return TConfiguredAction();
}

namespace {
class SetCompiled {
private:
TStreamerInfo* fInfo;
public:
SetCompiled(TStreamerInfo* iInfo): fInfo(iInfo) {}
~SetCompiled() { fInfo->SetBit(TStreamerInfo::kIsCompiled); }
};
}

//______________________________________________________________________________
void TStreamerInfo::Compile()
Expand Down Expand Up @@ -2300,7 +2309,7 @@ void TStreamerInfo::Compile()
fOffset = new Int_t[ndata+1];
fType = new Int_t[ndata+1];

SetBit(kIsCompiled);
SetCompiled setCompiledWhenFinished(this);
if (!fReadObjectWise) fReadObjectWise = new TStreamerInfoActions::TActionSequence(this,ndata);
if (!fWriteObjectWise) fWriteObjectWise = new TStreamerInfoActions::TActionSequence(this,ndata);

Expand Down

0 comments on commit 83e9a81

Please sign in to comment.