Skip to content

Commit

Permalink
Merge pull request #71 from Dr15Jones/threadSafeAllEnums
Browse files Browse the repository at this point in the history
Thread-safe interaction with all enum lists
  • Loading branch information
ktf committed Mar 3, 2015
2 parents 532dbea + 1428f9a commit 49c149d
Show file tree
Hide file tree
Showing 7 changed files with 486 additions and 51 deletions.
5 changes: 3 additions & 2 deletions core/base/src/TROOT.cxx
Expand Up @@ -111,7 +111,7 @@
#include "TInterpreter.h"
#include "TListOfTypes.h"
#include "TListOfDataMembers.h"
#include "TListOfEnums.h"
#include "TListOfEnumsWithLock.h"
#include "TListOfFunctions.h"
#include "TListOfFunctionTemplates.h"
#include "TFunctionTemplate.h"
Expand Down Expand Up @@ -1367,8 +1367,9 @@ TObject *TROOT::GetGeometry(const char *name) const
//______________________________________________________________________________
TCollection *TROOT::GetListOfEnums()
{
R__LOCKGUARD2(gROOTMutex);
if(!fEnums) {
fEnums = new TListOfEnums(0);
fEnums = new TListOfEnumsWithLock(0);
}
return fEnums;
}
Expand Down
2 changes: 2 additions & 0 deletions core/meta/inc/LinkDef.h
Expand Up @@ -70,6 +70,8 @@
#pragma link C++ class TListOfFunctionTemplates+;
#pragma link C++ class TListOfDataMembers-;
#pragma link C++ class TListOfEnums+;
#pragma link C++ class TListOfEnumsWithLock+;
#pragma link C++ class TListOfEnumsWithLockIter;
//for new protoclasses
#pragma link C++ class std::vector<TDataMember * >+;
#pragma link C++ class std::vector<TProtoClass::TProtoRealData >+;
Expand Down
61 changes: 33 additions & 28 deletions core/meta/inc/TListOfEnums.h
Expand Up @@ -36,6 +36,10 @@ class TEnum;
class TListOfEnums : public THashList
{
private:
friend class TCling;
friend class TClass;
friend class TProtoClass;

typedef TDictionary::DeclId_t DeclId_t;
TClass *fClass; //! Context of this list. Not owned.

Expand All @@ -44,44 +48,45 @@ class TListOfEnums : public THashList
Bool_t fIsLoaded; //! Mark whether Load was executed.
ULong64_t fLastLoadMarker; //! Represent interpreter state when we last did a full load.

TListOfEnums(const TListOfEnums&); // not implemented
TListOfEnums& operator=(const TListOfEnums&); // not implemented
TListOfEnums(const TListOfEnums&) = delete;
TListOfEnums& operator=(const TListOfEnums&) = delete;

void MapObject(TObject *obj);
void UnmapObject(TObject *obj);

public:
void Load();
void Unload();
void Unload(TEnum *e);
void SetClass(TClass* cl) { fClass = cl; }

TListOfEnums(TClass *cl = 0);
~TListOfEnums();
protected:
TClass* GetClass() const {return fClass;}
TExMap* GetIds() { return fIds;}
TEnum* FindUnloaded(const char* name) { return (TEnum*)fUnloaded->FindObject(name);}
TEnum *Get(DeclId_t id, const char *name);

virtual void Clear(Option_t *option);
virtual void Delete(Option_t *option="");
public:

using THashList::FindObject;
virtual TObject *FindObject(const char *name) const;
TListOfEnums(TClass *cl = 0);
~TListOfEnums() override;

TEnum *Get(DeclId_t id, const char *name);
void Clear(Option_t *option) override;
void Delete(Option_t *option="") override;

Bool_t IsLoaded() const { return fIsLoaded; }
void AddFirst(TObject *obj);
void AddFirst(TObject *obj, Option_t *opt);
void AddLast(TObject *obj);
void AddLast(TObject *obj, Option_t *opt);
void AddAt(TObject *obj, Int_t idx);
void AddAfter(const TObject *after, TObject *obj);
void AddAfter(TObjLink *after, TObject *obj);
void AddBefore(const TObject *before, TObject *obj);
void AddBefore(TObjLink *before, TObject *obj);

void RecursiveRemove(TObject *obj);
TObject *Remove(TObject *obj);
TObject *Remove(TObjLink *lnk);

void Load();
void Unload();
void Unload(TEnum *e);
void SetClass(TClass* cl) { fClass = cl; }
void AddFirst(TObject *obj) override;
void AddFirst(TObject *obj, Option_t *opt) override;
void AddLast(TObject *obj) override;
void AddLast(TObject *obj, Option_t *opt) override;
void AddAt(TObject *obj, Int_t idx) override;
void AddAfter(const TObject *after, TObject *obj) override;
void AddAfter(TObjLink *after, TObject *obj) override;
void AddBefore(const TObject *before, TObject *obj) override;
void AddBefore(TObjLink *before, TObject *obj) override;

void RecursiveRemove(TObject *obj) override;
TObject *Remove(TObject *obj) override;
TObject *Remove(TObjLink *lnk) override;

ClassDef(TListOfEnums,2); // List of TDataMembers for a class
};
Expand Down
103 changes: 103 additions & 0 deletions core/meta/inc/TListOfEnumsWithLock.h
@@ -0,0 +1,103 @@
// @(#)root/cont
// Author: Bianca-Cristina Cristescu February 2014

/*************************************************************************
* Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#ifndef ROOT_TListOfEnumsWithLock
#define ROOT_TListOfEnumsWithLock

//////////////////////////////////////////////////////////////////////////
// //
// TListOfEnumsWithLock //
// //
// A collection of TEnum objects designed for fast access given a //
// DeclId_t and for keep track of TEnum that were described //
// unloaded enum. //
// //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TListOfEnums
#include "TListOfEnums.h"
#endif

class TExMap;
class TEnum;

class TListOfEnumsWithLock : public TListOfEnums
{
private:
typedef TDictionary::DeclId_t DeclId_t;

TListOfEnumsWithLock(const TListOfEnumsWithLock&) = delete;
TListOfEnumsWithLock& operator=(const TListOfEnumsWithLock&) = delete;

public:

TListOfEnumsWithLock(TClass *cl = 0);
~TListOfEnumsWithLock() override;

void Clear(Option_t *option) override;
void Delete(Option_t *option="") override;

TObject *FindObject(const TObject* obj) const override;
TObject *FindObject(const char *name) const override;
TIterator *MakeIterator(Bool_t dir = kIterForward) const override;

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

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

Int_t GetSize() const override;

void AddFirst(TObject *obj) override;
void AddFirst(TObject *obj, Option_t *opt) override;
void AddLast(TObject *obj) override;
void AddLast(TObject *obj, Option_t *opt) override;
void AddAt(TObject *obj, Int_t idx) override;
void AddAfter(const TObject *after, TObject *obj) override;
void AddAfter(TObjLink *after, TObject *obj) override;
void AddBefore(const TObject *before, TObject *obj) override;
void AddBefore(TObjLink *before, TObject *obj) override;

void RecursiveRemove(TObject *obj) override;
TObject *Remove(TObject *obj) override;
TObject *Remove(TObjLink *lnk) override;

ClassDef(TListOfEnumsWithLock,2); // List of TDataMembers for a class
};


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

using TListIter::operator=;

TObject *Next();

ClassDef(TListOfEnumsWithLockIter,0)
};

#endif // ROOT_TListOfEnumsWithLock
20 changes: 18 additions & 2 deletions core/meta/src/TClass.cxx
Expand Up @@ -83,6 +83,7 @@
#include "TListOfFunctions.h"
#include "TListOfFunctionTemplates.h"
#include "TListOfEnums.h"
#include "TListOfEnumsWithLock.h"
#include "TViewPubDataMembers.h"
#include "TViewPubFunctions.h"

Expand Down Expand Up @@ -3327,16 +3328,31 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
}

if(not load) {
if(! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
R__LOCKGUARD(gInterpreterMutex);
if(fEnums) {
return fEnums.load();
}
//namespaces can have enums added to them
fEnums = new TListOfEnumsWithLock(this);
return fEnums;
}
//no one is supposed to modify the returned results
static TList s_list;
static TListOfEnums s_list;
return &s_list;
}

R__LOCKGUARD(gInterpreterMutex);
if(fEnums) {
return fEnums.load();
}
temp = new TListOfEnums(this);
if( (kIsClass | kIsStruct | kIsUnion) & fProperty) {
// For this case, the list will be immutable
temp = new TListOfEnums(this);
} else {
//namespaces can have enums added to them
temp = new TListOfEnumsWithLock(this);
}
temp->Load();
fEnums = temp;
return temp;
Expand Down
20 changes: 1 addition & 19 deletions core/meta/src/TListOfEnums.cxx
Expand Up @@ -176,25 +176,6 @@ void TListOfEnums::Delete(Option_t *option /* ="" */)
fIsLoaded = kFALSE;
}

//______________________________________________________________________________
TObject *TListOfEnums::FindObject(const char *name) const
{
// Specialize FindObject to do search for the
// a enum just by name or create it if its not already in the list

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

R__LOCKGUARD(gInterpreterMutex);

TInterpreter::DeclId_t decl;
if (fClass) decl = gInterpreter->GetEnum(fClass, name);
else decl = gInterpreter->GetEnum(0, name);
if (decl) result = const_cast<TListOfEnums *>(this)->Get(decl, name);
}
return result;
}

//______________________________________________________________________________
TEnum *TListOfEnums::Get(DeclId_t id, const char *name)
{
Expand Down Expand Up @@ -261,6 +242,7 @@ TEnum *TListOfEnums::Get(DeclId_t id, const char *name)
return e;
}


//______________________________________________________________________________
void TListOfEnums::UnmapObject(TObject *obj)
{
Expand Down

0 comments on commit 49c149d

Please sign in to comment.