Skip to content

Commit

Permalink
Merge pull request #61 from Dr15Jones/threadSafeTListOfFunctions
Browse files Browse the repository at this point in the history
Thread safe TListOfFunctions
  • Loading branch information
ktf committed Feb 16, 2015
2 parents f027d43 + 36ec545 commit 243fe6f
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 13 deletions.
1 change: 1 addition & 0 deletions core/meta/inc/LinkDef.h
Expand Up @@ -66,6 +66,7 @@
#pragma link C++ class std::vector<std::pair<Int_t, Int_t> >+;
#pragma link C++ class TFileMergeInfo;
#pragma link C++ class TListOfFunctions+;
#pragma link C++ class TListOfFunctionsIter;
#pragma link C++ class TListOfFunctionTemplates+;
#pragma link C++ class TListOfDataMembers-;
#pragma link C++ class TListOfEnums+;
Expand Down
2 changes: 1 addition & 1 deletion core/meta/inc/TClass.h
Expand Up @@ -187,7 +187,7 @@ friend class TProtoClass;
TListOfDataMembers*fData; //linked list for data members
TListOfEnums *fEnums; //linked list for the enums
TListOfFunctionTemplates *fFuncTemplate; //linked list for function templates [Not public until implemented as active list]
TListOfFunctions *fMethod; //linked list for methods
std::atomic<TListOfFunctions*> fMethod; //linked list for methods
TViewPubDataMembers*fAllPubData; //all public data members (including from base classes)
TViewPubFunctions *fAllPubMethod; //all public methods (including from base classes)
mutable TList *fClassMenuList; //list of class menu items
Expand Down
38 changes: 37 additions & 1 deletion core/meta/inc/TListOfFunctions.h
Expand Up @@ -63,10 +63,26 @@ class TListOfFunctions : public THashList
virtual void Clear(Option_t *option);
virtual void Delete(Option_t *option="");

using THashList::FindObject;
virtual TObject *FindObject(const TObject* obj) const;
virtual TObject *FindObject(const char *name) const;
virtual TList *GetListForObject(const char* name) const;
virtual TList *GetListForObject(const TObject* obj) const;
virtual TIterator *MakeIterator(Bool_t dir = kIterForward) const;

virtual TObject *At(Int_t idx) const;
virtual TObject *After(const TObject *obj) const;
virtual TObject *Before(const TObject *obj) const;
virtual TObject *First() const;
virtual TObjLink *FirstLink() const;
virtual TObject **GetObjectRef(const TObject *obj) const;
virtual TObject *Last() const;
virtual TObjLink *LastLink() const;

virtual Int_t GetLast() const;
virtual Int_t IndexOf(const TObject *obj) const;

virtual Int_t GetSize() const;


TFunction *Get(DeclId_t id);

Expand All @@ -91,4 +107,24 @@ class TListOfFunctions : public THashList
ClassDef(TListOfFunctions,0); // List of TFunctions for a class
};

//////////////////////////////////////////////////////////////////////////
// //
// TListOfFunctionsIter //
// //
// Iterator of TListOfFunctions. //
// //
//////////////////////////////////////////////////////////////////////////
class TListOfFunctionsIter : public TListIter
{
public:
TListOfFunctionsIter(const TListOfFunctions *l, Bool_t dir = kIterForward);

using TListIter::operator=;

TObject *Next();

ClassDef(TListOfFunctionsIter,0)
};


#endif // ROOT_TListOfFunctions
21 changes: 14 additions & 7 deletions core/meta/src/TClass.cxx
Expand Up @@ -77,6 +77,7 @@
#include <cmath>
#include <assert.h>
#include <vector>
#include <memory>

#include "TListOfDataMembers.h"
#include "TListOfFunctions.h"
Expand Down Expand Up @@ -1551,7 +1552,7 @@ TClass::~TClass()
delete fFuncTemplate; fFuncTemplate = 0;

if (fMethod)
fMethod->Delete();
(*fMethod).Delete();
delete fMethod; fMethod=0;

if (fRealData)
Expand Down Expand Up @@ -3369,10 +3370,10 @@ TList *TClass::GetListOfMethods(Bool_t load /* = kTRUE */)

R__LOCKGUARD(gInterpreterMutex);

if (!fMethod) fMethod = new TListOfFunctions(this);
if (!fMethod) GetMethodList();
if (load) {
if (gDebug>0) Info("GetListOfMethods","Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
fMethod->Load();
(*fMethod).Load();
}
return fMethod;
}
Expand All @@ -3381,7 +3382,7 @@ TList *TClass::GetListOfMethods(Bool_t load /* = kTRUE */)
TCollection *TClass::GetListOfMethodOverloads(const char* name) const
{
// Return the collection of functions named "name".
return ((TListOfFunctions*)fMethod)->GetListForObject(name);
return const_cast<TClass*>(this)->GetMethodList()->GetListForObject(name);
}


Expand Down Expand Up @@ -3735,7 +3736,7 @@ void TClass::ResetCaches()
if (fEnums)
fEnums->Unload();
if (fMethod)
fMethod->Unload();
(*fMethod).Unload();

delete fAllPubData; fAllPubData = 0;

Expand Down Expand Up @@ -3864,7 +3865,13 @@ TListOfFunctions *TClass::GetMethodList()
// the internal type of fMethod and thus can not be made public.
// It also never 'loads' the content of the list.

if (!fMethod) fMethod = new TListOfFunctions(this);
if (!fMethod) {
std::unique_ptr<TListOfFunctions> temp{ new TListOfFunctions(this) };
TListOfFunctions* expected = nullptr;
if(fMethod.compare_exchange_strong(expected, temp.get()) ) {
temp.release();
}
}
return fMethod;
}

Expand Down Expand Up @@ -5606,7 +5613,7 @@ void TClass::SetUnloaded()
fTypeInfo = 0;

if (fMethod) {
fMethod->Unload();
(*fMethod).Unload();
}
if (fData) {
fData->Unload();
Expand Down
120 changes: 116 additions & 4 deletions core/meta/src/TListOfFunctions.cxx
Expand Up @@ -176,11 +176,10 @@ TObject *TListOfFunctions::FindObject(const char *name) const
// Specialize FindObject to do search for the
// a function just by name or create it if its not already in the list

R__LOCKGUARD(gInterpreterMutex);
TObject *result = THashList::FindObject(name);
if (!result) {

R__LOCKGUARD(gInterpreterMutex);

TInterpreter::DeclId_t decl;
if (fClass) decl = gInterpreter->GetFunction(fClass->GetClassInfo(),name);
else decl = gInterpreter->GetFunction(0,name);
Expand Down Expand Up @@ -254,6 +253,7 @@ TFunction *TListOfFunctions::Get(DeclId_t id)

if (!id) return 0;

R__LOCKGUARD(gInterpreterMutex);
TFunction *f = (TFunction*)fIds->GetValue((Long64_t)id);
if (!f) {
if (fClass) {
Expand All @@ -262,8 +262,6 @@ TFunction *TListOfFunctions::Get(DeclId_t id)
if (!gInterpreter->ClassInfo_Contains(0,id)) return 0;
}

R__LOCKGUARD(gInterpreterMutex);

MethodInfo_t *m = gInterpreter->MethodInfo_Factory(id);

// Let's see if this is a reload ...
Expand Down Expand Up @@ -426,3 +424,117 @@ void TListOfFunctions::Unload(TFunction *func)
fUnloaded->Add(func);
}
}

//______________________________________________________________________________
TObject* TListOfFunctions::FindObject(const TObject* obj) const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::FindObject(obj);
}

//______________________________________________________________________________
TIterator* TListOfFunctions::MakeIterator(Bool_t dir ) const
{
R__LOCKGUARD(gInterpreterMutex);
return new TListOfFunctionsIter(this,dir);
}

//______________________________________________________________________________
TObject* TListOfFunctions::At(Int_t idx) const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::At(idx);
}

//______________________________________________________________________________
TObject* TListOfFunctions::After(const TObject *obj) const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::After(obj);
}

//______________________________________________________________________________
TObject* TListOfFunctions::Before(const TObject *obj) const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::Before(obj);
}

//______________________________________________________________________________
TObject* TListOfFunctions::First() const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::First();
}

//______________________________________________________________________________
TObjLink* TListOfFunctions::FirstLink() const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::FirstLink();
}

//______________________________________________________________________________
TObject** TListOfFunctions::GetObjectRef(const TObject *obj) const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::GetObjectRef(obj);
}

//______________________________________________________________________________
TObject* TListOfFunctions::Last() const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::Last();
}

//______________________________________________________________________________
TObjLink* TListOfFunctions::LastLink() const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::LastLink();
}


//______________________________________________________________________________
Int_t TListOfFunctions::GetLast() const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::GetLast();
}

//______________________________________________________________________________
Int_t TListOfFunctions::IndexOf(const TObject *obj) const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::IndexOf(obj);
}


//______________________________________________________________________________
Int_t TListOfFunctions::GetSize() const
{
R__LOCKGUARD(gInterpreterMutex);
return THashList::GetSize();
}

//////////////////////////////////////////////////////////////////////////
// //
// TListOfFunctionsIter //
// //
// Iterator for TListOfFunctions. //
// //
//////////////////////////////////////////////////////////////////////////

ClassImp(TListOfFunctionsIter)

//______________________________________________________________________________
TListOfFunctionsIter::TListOfFunctionsIter(const TListOfFunctions *l, Bool_t dir ):
TListIter(l,dir) {}

//______________________________________________________________________________
TObject *TListOfFunctionsIter::Next()
{
R__LOCKGUARD(gInterpreterMutex);
return TListIter::Next();
}

0 comments on commit 243fe6f

Please sign in to comment.