Skip to content

Protect global list of functions from concurrent access #24

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

Closed
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
14 changes: 11 additions & 3 deletions core/base/src/TROOT.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,10 @@ TObject *TROOT::FindObject(const char *name) const

temp = fFiles->FindObject(name); if (temp) return temp;
temp = fMappedFiles->FindObject(name); if (temp) return temp;
temp = fFunctions->FindObject(name); if (temp) return temp;
{
R__LOCKGUARD2(gROOTMutex);
temp = fFunctions->FindObject(name); if (temp) return temp;
}
temp = fGeometries->FindObject(name); if (temp) return temp;
temp = fCanvases->FindObject(name); if (temp) return temp;
temp = fStyles->FindObject(name); if (temp) return temp;
Expand Down Expand Up @@ -852,6 +855,7 @@ TObject *TROOT::FindSpecialObject(const char *name, void *&where)
where = fMappedFiles;
}
if (!temp) {
R__LOCKGUARD2(gROOTMutex);
temp = fFunctions->FindObject(name);
where = fFunctions;
}
Expand Down Expand Up @@ -1113,11 +1117,15 @@ TObject *TROOT::GetFunction(const char *name) const
return 0;
}

TObject *f1 = fFunctions->FindObject(name);
if (f1) return f1;
{
R__LOCKGUARD2(gROOTMutex);
TObject *f1 = fFunctions->FindObject(name);
if (f1) return f1;
}

gROOT->ProcessLine("TF1::InitStandardFunctions();");

R__LOCKGUARD2(gROOTMutex);
return fFunctions->FindObject(name);
}

Expand Down
89 changes: 60 additions & 29 deletions hist/hist/src/TF1.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "TClass.h"
#include "TMethodCall.h"
#include "TF1Helper.h"
#include "TVirtualMutex.h"
#include "Math/WrappedFunction.h"
#include "Math/WrappedTF1.h"
#include "Math/BrentRootFinder.h"
Expand Down Expand Up @@ -502,9 +503,9 @@ TF1::TF1(const char *name, Double_t xmin, Double_t xmax, Int_t npar)
fCintFunc = 0;
fNdim = 1;

TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
SetName(name);
//Don't call SetName since it would just be TNamed::SetName which would
// attempt to refresh gPad which is not necessary
fName = name;

if (gStyle) {
SetLineColor(gStyle->GetFuncColor());
Expand All @@ -519,7 +520,12 @@ TF1::TF1(const char *name, Double_t xmin, Double_t xmax, Int_t npar)
fMethodCall = new TMethodCall();
fMethodCall->InitWithPrototype(name,"Double_t*,Double_t*");
fNumber = -1;
gROOT->GetListOfFunctions()->Add(this);
{
R__LOCKGUARD2(gROOTMutex);
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
gROOT->GetListOfFunctions()->Add(this);
}
if (! fMethodCall->IsValid() ) {
Error("TF1","No function found with the signature %s(Double_t*,Double_t*)",name);
}
Expand Down Expand Up @@ -591,9 +597,9 @@ TF1::TF1(const char *name,void *fcn, Double_t xmin, Double_t xmax, Int_t npar)
fCintFunc = 0;
fNdim = 1;

TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
SetName(name);
//Don't call SetName since it would just be TNamed::SetName which would
// attempt to refresh gPad which is not necessary
fName = name;

if (gStyle) {
SetLineColor(gStyle->GetFuncColor());
Expand All @@ -609,7 +615,12 @@ TF1::TF1(const char *name,void *fcn, Double_t xmin, Double_t xmax, Int_t npar)
fMethodCall = new TMethodCall();
fMethodCall->InitWithPrototype(funcname,"Double_t*,Double_t*");
fNumber = -1;
gROOT->GetListOfFunctions()->Add(this);
{
R__LOCKGUARD2(gROOTMutex);
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
gROOT->GetListOfFunctions()->Add(this);
}
if (! fMethodCall->IsValid() ) {
Error("TF1","No function found with the signature %s(Double_t*,Double_t*)",funcname);
}
Expand Down Expand Up @@ -679,12 +690,17 @@ TF1::TF1(const char *name,Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin
fMaximum = -1111;
fNdim = 1;

// Store formula in linked list of formula in ROOT
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
SetName(name);
gROOT->GetListOfFunctions()->Add(this);

//Don't call SetName since it would just be TNamed::SetName which would
// attempt to refresh gPad which is not necessary
fName = name;
{
R__LOCKGUARD2(gROOTMutex);
// Store formula in linked list of formula in ROOT
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
gROOT->GetListOfFunctions()->Add(this);
}

if (!gStyle) return;
SetLineColor(gStyle->GetFuncColor());
SetLineWidth(gStyle->GetFuncWidth());
Expand Down Expand Up @@ -751,12 +767,16 @@ TF1::TF1(const char *name,Double_t (*fcn)(const Double_t *, const Double_t *), D
fMaximum = -1111;
fNdim = 1;

// Store formula in linked list of formula in ROOT
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
SetName(name);
gROOT->GetListOfFunctions()->Add(this);

//Don't call SetName since it would just be TNamed::SetName which would
// attempt to refresh gPad which is not necessary
fName = name;
{
R__LOCKGUARD2(gROOTMutex);
// Store formula in linked list of formula in ROOT
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
gROOT->GetListOfFunctions()->Add(this);
}
if (!gStyle) return;
SetLineColor(gStyle->GetFuncColor());
SetLineWidth(gStyle->GetFuncWidth());
Expand Down Expand Up @@ -837,11 +857,16 @@ void TF1::CreateFromFunctor(const char *name, Int_t npar)
fParMax = 0;
}

// Store formula in linked list of formula in ROOT
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
SetName(name);
gROOT->GetListOfFunctions()->Add(this);
//Don't call SetName since it would just be TNamed::SetName which would
// attempt to refresh gPad which is not necessary
fName = name;
{
R__LOCKGUARD2(gROOTMutex);
// Store formula in linked list of formula in ROOT
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
gROOT->GetListOfFunctions()->Add(this);
}

if (!gStyle) return;
SetLineColor(gStyle->GetFuncColor());
Expand Down Expand Up @@ -944,9 +969,9 @@ void TF1::CreateFromCintClass(const char *name,void *ptr, Double_t xmin, Double_
fMethodCall = 0;
fNdim = 1;

TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
SetName(name);
//Don't call SetName since it would just be TNamed::SetName which would
// attempt to refresh gPad which is not necessary
fName = name;

if (gStyle) {
SetLineColor(gStyle->GetFuncColor());
Expand Down Expand Up @@ -976,7 +1001,12 @@ void TF1::CreateFromCintClass(const char *name,void *ptr, Double_t xmin, Double_
}

fNumber = -1;
gROOT->GetListOfFunctions()->Add(this);
{
R__LOCKGUARD2(gROOTMutex);
TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(name);
gROOT->GetListOfFunctions()->Remove(f1old);
gROOT->GetListOfFunctions()->Add(this);
}
if (! fMethodCall->IsValid() ) {
if (methodName)
Error("TF1","No function found in class %s with the signature %s(Double_t*,Double_t*)",className,methodName);
Expand Down Expand Up @@ -2408,6 +2438,7 @@ void TF1::InitStandardFunctions()
// Create the basic function objects

TF1 *f1;
R__LOCKGUARD2(gROOTMutex);
if (!gROOT->GetListOfFunctions()->FindObject("gaus")) {
f1 = new TF1("gaus","gaus",-1,1); f1->SetParameters(1,0,1);
f1 = new TF1("gausn","gausn",-1,1); f1->SetParameters(1,0,1);
Expand Down
42 changes: 30 additions & 12 deletions hist/hist/src/TFormula.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "TObjString.h"
#include "TError.h"
#include "TFormulaPrimitive.h"
#include "TVirtualMutex.h"

#ifdef WIN32
#pragma optimize("",off)
Expand Down Expand Up @@ -225,16 +226,18 @@ TFormula::TFormula(const char *name,const char *expression) :

// Store formula in linked list of formula in ROOT

TFormula *old = (TFormula*)gROOT->GetListOfFunctions()->FindObject(name);
if (old) {
gROOT->GetListOfFunctions()->Remove(old);
}

if (strcmp(name,"x")==0 || strcmp(name,"y")==0 ||
strcmp(name,"z")==0 || strcmp(name,"t")==0 )
{
Error("TFormula","The name \'%s\' is reserved as a TFormula variable name.\n"
"\tThis function will not be registered in the list of functions",name);
} else {
R__LOCKGUARD2(gROOTMutex);
TFormula *old = (TFormula*)gROOT->GetListOfFunctions()->FindObject(name);
if (old) {
gROOT->GetListOfFunctions()->Remove(old);
}
gROOT->GetListOfFunctions()->Add(this);
}
}
Expand Down Expand Up @@ -284,7 +287,10 @@ TFormula::~TFormula()
{
// Formula default destructor.

if (gROOT) gROOT->GetListOfFunctions()->Remove(this);
if (gROOT) {
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfFunctions()->Remove(this);
}

ClearFormula();
}
Expand Down Expand Up @@ -673,7 +679,7 @@ void TFormula::Analyze(const char *schain, Int_t &err, Int_t offset)
TString s1,s2,s3,ctemp;

TString chaine = schain;
TFormula *oldformula;
const TFormula *oldformula;
Int_t modulo,plus,puiss10,puiss10bis,moins,multi,divi,puiss,et,ou,petit,grand,egal,diff,peteg,grdeg,etx,oux,rshift,lshift,tercond,terelse;
char t;
TString slash("/"), escapedSlash("\\/");
Expand Down Expand Up @@ -1299,7 +1305,10 @@ void TFormula::Analyze(const char *schain, Int_t &err, Int_t offset)
// Look for an already defined expression

if (find==0) {
oldformula = (TFormula*)gROOT->GetListOfFunctions()->FindObject((const char*)chaine);
{
R__LOCKGUARD2(gROOTMutex);
oldformula = (const TFormula*)gROOT->GetListOfFunctions()->FindObject((const char*)chaine);
}
if (oldformula && strcmp(schain,oldformula->GetTitle())) {
Int_t nprior = fNpar;
Analyze(oldformula->GetExpFormula(),err,fNpar);
Expand Down Expand Up @@ -3271,7 +3280,10 @@ void TFormula::ProcessLinear(TString &formula)
Error("TFormula", "f_linear not allocated");
return;
}
gROOT->GetListOfFunctions()->Remove(f);
{
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfFunctions()->Remove(f);
}
f->SetBit(kNotGlobal, 1);
fLinearParts.Add(f);
}
Expand Down Expand Up @@ -3385,7 +3397,10 @@ void TFormula::Streamer(TBuffer &b)
return;
}
b.ReadClassBuffer(TFormula::Class(), this, v, R__s, R__c);
if (!TestBit(kNotGlobal)) gROOT->GetListOfFunctions()->Add(this);
if (!TestBit(kNotGlobal)) {
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfFunctions()->Add(this);
}

// We need to reinstate (if possible) the TMethodCall.
if (fFunctions.GetLast()>=0) {
Expand Down Expand Up @@ -3428,9 +3443,12 @@ void TFormula::Streamer(TBuffer &b)
}
Int_t i;
for (i=0;i<fNoper;i++) fExpr[i].Streamer(b);
for (i=0;i<fNpar;i++) fNames[i].Streamer(b);
if (gROOT->GetListOfFunctions()->FindObject(GetName())) return;
gROOT->GetListOfFunctions()->Add(this);
for (i=0;i<fNpar;i++) fNames[i].Streamer(b);
{
R__LOCKGUARD2(gROOTMutex);
if (gROOT->GetListOfFunctions()->FindObject(GetName())) return;
gROOT->GetListOfFunctions()->Add(this);
}
b.CheckByteCount(R__s, R__c, TFormula::IsA());

Convert(v);
Expand Down
10 changes: 7 additions & 3 deletions hist/hist/src/TFormulaPrimitive.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@

#include "TFormulaPrimitive.h"
#include "TMath.h"
#include "TVirtualMutex.h"
#ifdef WIN32
#pragma optimize("",off)
#endif

static TVirtualMutex* gTFormulaPrimativeListMutex = 0;

void TMath_GenerInterface();

ClassImp(TFormulaPrimitive)
Expand Down Expand Up @@ -189,7 +192,7 @@ Int_t TFormulaPrimitive::AddFormula(TFormulaPrimitive * formula)
{
// Add formula to the list of primitive formulas.
// If primitive formula already defined do nothing.

R__LOCKGUARD2(gTFormulaPrimativeListMutex);
if (fgListOfFunction == 0) BuildBasicFormulas();
if (FindFormula(formula->GetName(),formula->fNArguments)){
delete formula;
Expand Down Expand Up @@ -308,6 +311,7 @@ namespace TFastFun {
TFormulaPrimitive* TFormulaPrimitive::FindFormula(const char* name)
{
// Find the formula in the list of formulas.
R__LOCKGUARD2(gTFormulaPrimativeListMutex);
if (!fgListOfFunction) {
BuildBasicFormulas();
}
Expand All @@ -324,7 +328,7 @@ TFormulaPrimitive* TFormulaPrimitive::FindFormula(const char* name)
TFormulaPrimitive* TFormulaPrimitive::FindFormula(const char* name, UInt_t nargs)
{
// Find the formula in the list of formulas.

R__LOCKGUARD2(gTFormulaPrimativeListMutex);
if (!fgListOfFunction) {
BuildBasicFormulas();
}
Expand Down Expand Up @@ -409,7 +413,7 @@ Double_t TFastFun::Gausn(Double_t x, Double_t mean, Double_t sigma)
Int_t TFormulaPrimitive::BuildBasicFormulas()
{
// Built-in functions.

R__LOCKGUARD2(gTFormulaPrimativeListMutex);
if (fgListOfFunction==0) {
fgListOfFunction = new TObjArray(1000);
fgListOfFunction->SetOwner(kTRUE);
Expand Down