Skip to content

Commit

Permalink
[rbrowsable] fix potential ownership problem
Browse files Browse the repository at this point in the history
If objects like TH1 or TF1 should be owned by TObjectHolder,
unregister them from global lists which can destroy them
  • Loading branch information
linev authored and hristov committed Aug 27, 2021
1 parent 7fb3834 commit 23754e7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
9 changes: 8 additions & 1 deletion gui/browsable/inc/ROOT/Browsable/TObjectHolder.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@ protected:
void *AccessObject() final { return fOwner ? nullptr : fObj; }
void *TakeObject() final;
RHolder *DoCopy() const final { return new TObjectHolder(fObj); }
void ClearROOTOwnership(TObject *obj);
public:
TObjectHolder(TObject *obj, bool owner = false) { fObj = obj; fOwner = owner; }
TObjectHolder(TObject *obj, bool owner = false)
{
fObj = obj;
fOwner = owner;
if (fOwner) ClearROOTOwnership(fObj);
}

virtual ~TObjectHolder()
{
if (fOwner) delete fObj;
Expand Down
25 changes: 19 additions & 6 deletions gui/browsable/src/TObjectHolder.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,26 @@

using namespace ROOT::Experimental::Browsable;

///////////////////////////////////////////////////////////////////////////
/// Check if object is not registered in some global lists
/// Prevent double deletion

void TObjectHolder::ClearROOTOwnership(TObject *obj)
{
if (obj && obj->InheritsFrom("TH1")) {
std::stringstream cmd;
cmd << "((TH1 *) " << std::hex << std::showbase << (size_t)obj << ")->SetDirectory(nullptr);";
gROOT->ProcessLine(cmd.str().c_str());
} else if (obj && obj->InheritsFrom("TF1")) {
std::stringstream cmd;
cmd << "((TF1 *) " << std::hex << std::showbase << (size_t)obj << ")->AddToGlobalList(kFALSE);";
gROOT->ProcessLine(cmd.str().c_str());
}
}

///////////////////////////////////////////////////////////////////////////
/// Return TObject instance with ownership
/// If object is not owned by the holder, it will be cloned (with few exceptions)
/// If object is not owned by the holder, it will be cloned (except TDirectory or TTree classes)

void *TObjectHolder::TakeObject()
{
Expand All @@ -26,11 +43,7 @@ void *TObjectHolder::TakeObject()
fOwner = false;
} else if (fObj && !fObj->IsA()->InheritsFrom("TDirectory") && !fObj->IsA()->InheritsFrom("TTree")) {
res = fObj->Clone();
if (res && res->InheritsFrom("TH1")) {
std::stringstream cmd;
cmd << "((TH1 *) " << std::hex << std::showbase << (size_t)res << ")->SetDirectory(nullptr);";
gROOT->ProcessLine(cmd.str().c_str());
}
ClearROOTOwnership(res);
} else {
res = nullptr;
}
Expand Down

0 comments on commit 23754e7

Please sign in to comment.