Skip to content

Commit 21930e1

Browse files
fix: Handle Sink/Source ownership more properly
FairRootManager and FairRun both used to `delete` fSink and fSource. In specific situations (FairRootManager getting destructed before FairRun) this leads to a double delete! Deprecate the old FairRootManager::Set{Source,Sink} APIs that take something like an owning pointer. FairRootManager should only have a non-owning reference to sink and source. To allow FairRun to set it, `friend` it from FairRootManager. See: #1418 (see "Double deleting of file source in FairRootManager and FairRun")
1 parent 3385d5e commit 21930e1

3 files changed

Lines changed: 28 additions & 37 deletions

File tree

fairroot/base/steer/FairRootManager.cxx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/********************************************************************************
2-
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
2+
* Copyright (C) 2014-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
33
* *
44
* This software is distributed under the terms of the *
55
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -84,10 +84,8 @@ FairRootManager::FairRootManager()
8484
, fBrPerMap()
8585
, fFillLastData(kFALSE)
8686
, fEntryNr(0)
87-
, fSource(0)
8887
, fSignalChainList()
8988
, fEventHeader(new FairEventHeader())
90-
, fSink(nullptr)
9189
, fUseFairLinks(kFALSE)
9290
, fFinishRun(kFALSE)
9391
{
@@ -105,10 +103,6 @@ FairRootManager::~FairRootManager()
105103

106104
delete fEventHeader;
107105
delete fSourceChain;
108-
if (fSink)
109-
delete fSink;
110-
if (fSource)
111-
delete fSource;
112106

113107
// Global cleanup
114108

@@ -388,6 +382,7 @@ void FairRootManager::WriteFolder()
388382
fSink->WriteObject(fTimeBasedBranchNameList, "TimeBasedBranchList", TObject::kSingleKey);
389383
}
390384
}
385+
391386
Bool_t FairRootManager::SpecifyRunId()
392387
{
393388
if (!fSource) {
@@ -892,7 +887,7 @@ std::string FairRootManager::GetNameFromFile(const char* namekind)
892887
{
893888
std::string default_name = "";
894889

895-
if (strcmp(namekind, "treename=") && strcmp(namekind, "foldername=")) {
890+
if ((strcmp(namekind, "treename=") != 0) && (strcmp(namekind, "foldername=") != 0)) {
896891
LOG(fatal) << "FairRootManager, requested " << namekind << ", while only treename= and foldername= available.";
897892
return default_name;
898893
}

fairroot/base/steer/FairRootManager.h

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/********************************************************************************
2-
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
2+
* Copyright (C) 2014-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
33
* *
44
* This software is distributed under the terms of the *
55
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -8,7 +8,7 @@
88
#ifndef FAIR_ROOT_MANAGER_H
99
#define FAIR_ROOT_MANAGER_H
1010

11-
#include "FairLogger.h"
11+
#include "FairMemory.h"
1212
#include "FairSink.h"
1313
#include "FairSource.h"
1414

@@ -17,7 +17,8 @@
1717
#include <TObject.h> // for TObject
1818
#include <TRefArray.h> // for TRefArray
1919
#include <TString.h> // for TString, operator<
20-
#include <map> // for map, multimap, etc
20+
#include <fairlogger/Logger.h>
21+
#include <map> // for map, multimap, etc
2122
#include <memory>
2223
#include <string>
2324
#include <type_traits> // is_pointer, remove_pointer, is_const, remove...
@@ -49,6 +50,8 @@ class TTree;
4950

5051
class FairRootManager : public TObject
5152
{
53+
friend class FairRun;
54+
5255
public:
5356
/**dtor*/
5457
~FairRootManager() override;
@@ -218,21 +221,12 @@ class FairRootManager : public TObject
218221
void SetUseFairLinks(Bool_t val) { fUseFairLinks = val; };
219222
Bool_t GetUseFairLinks() const { return fUseFairLinks; };
220223

221-
/**
222-
* @param Status : if true all inputs are mixed, i.e: each read event will take one entry from each input and put
223-
* them in one big event and send it to the next step
224-
*/
225-
/* void SetMixAllInputs(Bool_t Status) { */
226-
/* fMixAllInputs=kTRUE; */
227-
/* } */
228-
229-
/** These methods have been moved to the FairFileSource */
230-
void SetSource(FairSource* tempSource) { fSource = tempSource; }
231-
FairSource* GetSource() { return fSource; }
224+
[[deprecated]] void SetSource(FairSource* source) { fSource = std::unique_ptr<FairSource>{source}; }
225+
FairSource* GetSource() { return fSource.get(); }
232226
Bool_t InitSource();
233227

234-
void SetSink(FairSink* tempSink) { fSink = tempSink; }
235-
FairSink* GetSink() { return fSink; }
228+
[[deprecated]] void SetSink(FairSink* sink) { fSink = std::unique_ptr<FairSink>{sink}; }
229+
FairSink* GetSink() { return fSink.get(); }
236230
Bool_t InitSink();
237231

238232
void SetListOfFolders(TObjArray* ta) { fListFolder = ta; }
@@ -383,14 +377,14 @@ class FairRootManager : public TObject
383377

384378
TObjArray* fListFolder{nullptr}; //!
385379

386-
FairSource* fSource;
380+
fairroot::detail::maybe_owning_ptr<FairSource> fSource; //!
387381

388382
TChain* fSourceChain = nullptr;
389383
std::map<UInt_t, TChain*> fSignalChainList; //!
390384

391385
FairEventHeader* fEventHeader;
392386

393-
FairSink* fSink;
387+
fairroot::detail::maybe_owning_ptr<FairSink> fSink; //!
394388

395389
Bool_t fUseFairLinks; //!
396390
Bool_t fFinishRun; //!

fairroot/base/steer/FairRun.cxx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/********************************************************************************
2-
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
2+
* Copyright (C) 2014-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
33
* *
44
* This software is distributed under the terms of the *
55
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -30,6 +30,9 @@
3030
#include <TROOT.h> // fot gROOT
3131
#include <cassert> // for... well, assert
3232

33+
using fairroot::detail::maybe_owning_ptr;
34+
using fairroot::detail::non_owning;
35+
3336
TMCThreadLocal FairRun* FairRun::fRunInstance = nullptr;
3437

3538
FairRun* FairRun::Instance() { return fRunInstance; }
@@ -82,9 +85,10 @@ FairRun::~FairRun()
8285
{
8386
LOG(debug) << "Enter Destructor of FairRun";
8487

85-
// So that FairRootManager does not try to delete these, because we will do that:
86-
fRootManager->SetSource(nullptr);
87-
fRootManager->SetSink(nullptr);
88+
// So that FairRootManager does not have a dangling reference
89+
// to these. Our unique_ptr will destruct them.
90+
fRootManager->fSource.reset();
91+
fRootManager->fSink.reset();
8892

8993
if (fTask) {
9094
// FairRunAna added it, but let's remove it here, because we own it
@@ -186,23 +190,22 @@ Bool_t FairRun::GetWriteRunInfoFile()
186190
void FairRun::SetSink(std::unique_ptr<FairSink> newsink)
187191
{
188192
fSink = std::move(newsink);
189-
fRootManager->SetSink(fSink.get());
193+
fRootManager->fSink = maybe_owning_ptr<FairSink>{fSink.get(), non_owning};
190194
fUserOutputFileName = fSink->GetFileName();
191195
}
192196

193197
void FairRun::SetSink(FairSink* tempSink)
194198
{
195199
fSink.reset(tempSink);
196-
fRootManager->SetSink(fSink.get());
200+
fRootManager->fSink = maybe_owning_ptr<FairSink>{fSink.get(), non_owning};
197201
fUserOutputFileName = fSink->GetFileName();
198202
}
199203

200204
void FairRun::SetOutputFile(const char* fname)
201205
{
202206
LOG(warning) << "FairRun::SetOutputFile() deprecated. Use FairRootFileSink.";
203207
fSink = std::make_unique<FairRootFileSink>(fname);
204-
if (fRootManager)
205-
fRootManager->SetSink(fSink.get());
208+
fRootManager->fSink = maybe_owning_ptr<FairSink>{fSink.get(), non_owning};
206209
fUserOutputFileName = fname;
207210
}
208211

@@ -216,8 +219,7 @@ void FairRun::SetOutputFileName(const TString& name)
216219
{
217220
LOG(warning) << "FairRun::SetOutputFileName() deprecated. Use FairRootFileSink.";
218221
fSink = std::make_unique<FairRootFileSink>(name);
219-
if (fRootManager)
220-
fRootManager->SetSink(fSink.get());
222+
fRootManager->fSink = maybe_owning_ptr<FairSink>{fSink.get(), non_owning};
221223
fUserOutputFileName = name;
222224
}
223225

@@ -256,7 +258,7 @@ void FairRun::AddAlignmentMatrices(const std::map<std::string, TGeoHMatrix>& ali
256258

257259
void FairRun::SetSource(FairSource* othersource)
258260
{
259-
fRootManager->SetSource(othersource);
261+
fRootManager->fSource = maybe_owning_ptr<FairSource>{othersource, non_owning};
260262
fSource.reset(othersource);
261263
}
262264

0 commit comments

Comments
 (0)