diff --git a/tree/dataframe/inc/ROOT/RDF/RAction.hxx b/tree/dataframe/inc/ROOT/RDF/RAction.hxx index c71b0dd38b889d793d39a3e730bb77575fa7b000..a4bc04cf7a828b6af33242a63f48d81464235537 100644 --- a/tree/dataframe/inc/ROOT/RDF/RAction.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RAction.hxx @@ -16,6 +16,7 @@ #include "ROOT/RDF/NodesUtils.hxx" // InitRDFValues #include "ROOT/RDF/Utils.hxx" // ColumnNames_t #include "ROOT/RDF/RColumnValue.hxx" +#include "ROOT/RDF/RLoopManager.hxx" #include <cstddef> // std::size_t #include <memory> @@ -117,6 +118,9 @@ public: RActionCRTP(const RActionCRTP &) = delete; RActionCRTP &operator=(const RActionCRTP &) = delete; + // must call Deregister here, before fPrevDataFrame is destroyed, + // otherwise if fPrevDataFrame is fLoopManager we get a use after delete + ~RActionCRTP() { fLoopManager->Deregister(this); } Helper &GetHelper() { return fHelper; } diff --git a/tree/dataframe/inc/ROOT/RDF/RActionBase.hxx b/tree/dataframe/inc/ROOT/RDF/RActionBase.hxx index b42c4370b8f35e1d472ce1e1989b6be4a7af9cbc..ed5217ef5a7ba1bd377e16f2cbfd4b976013123b 100644 --- a/tree/dataframe/inc/ROOT/RDF/RActionBase.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RActionBase.hxx @@ -42,11 +42,12 @@ bool CheckIfDefaultOrDSColumn(const std::string &name, } // namespace GraphDrawing class RActionBase { -private: +protected: /// A raw pointer to the RLoopManager at the root of this functional graph. /// Never null: children nodes have shared ownership of parent nodes in the graph. RLoopManager *fLoopManager; +private: const unsigned int fNSlots; ///< Number of thread slots used by this node. bool fHasRun = false; const ColumnNames_t fColumnNames; diff --git a/tree/dataframe/inc/ROOT/RDF/RFilter.hxx b/tree/dataframe/inc/ROOT/RDF/RFilter.hxx index feb00e78a72433996381e6e9ee38bdd6f6c4b975..095461d899b4aab2e2cd16ecda1a44286bc1525a 100644 --- a/tree/dataframe/inc/ROOT/RDF/RFilter.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RFilter.hxx @@ -16,6 +16,7 @@ #include "ROOT/RDF/NodesUtils.hxx" #include "ROOT/RDF/Utils.hxx" #include "ROOT/RDF/RFilterBase.hxx" +#include "ROOT/RDF/RLoopManager.hxx" #include "ROOT/RIntegerSequence.hxx" #include "ROOT/TypeTraits.hxx" #include "RtypesCore.h" @@ -69,6 +70,9 @@ public: RFilter(const RFilter &) = delete; RFilter &operator=(const RFilter &) = delete; + // must call Deregister here, before fPrevDataFrame is destroyed, + // otherwise if fPrevDataFrame is fLoopManager we get a use after delete + ~RFilter() { fLoopManager->Deregister(this); } bool CheckFilters(unsigned int slot, Long64_t entry) final { diff --git a/tree/dataframe/inc/ROOT/RDF/RRange.hxx b/tree/dataframe/inc/ROOT/RDF/RRange.hxx index f0e2c2ed49f07202b08853dee7e4c18bddad2bfc..e7a91417d17374bc61c681745c7ee5b04425ffa7 100644 --- a/tree/dataframe/inc/ROOT/RDF/RRange.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RRange.hxx @@ -11,6 +11,7 @@ #ifndef ROOT_RDFRANGE #define ROOT_RDFRANGE +#include "ROOT/RDF/RLoopManager.hxx" #include "ROOT/RDF/RRangeBase.hxx" #include "RtypesCore.h" @@ -43,6 +44,9 @@ public: RRange(const RRange &) = delete; RRange &operator=(const RRange &) = delete; + // must call Deregister here, before fPrevDataFrame is destroyed, + // otherwise if fPrevDataFrame is fLoopManager we get a use after delete + ~RRange() { fLoopManager->Deregister(this); } /// Ranges act as filters when it comes to selecting entries that downstream nodes should process bool CheckFilters(unsigned int slot, Long64_t entry) final diff --git a/tree/dataframe/src/RActionBase.cxx b/tree/dataframe/src/RActionBase.cxx index d3e017a67dab9687895ac77439abff6b94254ea6..9af61f7e3c3119fa39d09b8c370921de9ab8a61c 100644 --- a/tree/dataframe/src/RActionBase.cxx +++ b/tree/dataframe/src/RActionBase.cxx @@ -16,7 +16,5 @@ using namespace ROOT::Internal::RDF; RActionBase::RActionBase(RLoopManager *lm, const ColumnNames_t &colNames, const RBookedCustomColumns &customColumns) : fLoopManager(lm), fNSlots(lm->GetNSlots()), fColumnNames(colNames), fCustomColumns(customColumns) { } -RActionBase::~RActionBase() -{ - fLoopManager->Deregister(this); -} +// outlined to pin virtual table +RActionBase::~RActionBase() {} diff --git a/tree/dataframe/src/RFilterBase.cxx b/tree/dataframe/src/RFilterBase.cxx index de9b0fc3e270cbfe6d9b2c3c0a94ba74bc440a56..89cc938ea547a980229cf7f8a41c82d4167fa580 100644 --- a/tree/dataframe/src/RFilterBase.cxx +++ b/tree/dataframe/src/RFilterBase.cxx @@ -9,8 +9,8 @@ *************************************************************************/ #include "ROOT/RDF/RCutFlowReport.hxx" -#include "ROOT/RDF/RLoopManager.hxx" #include "ROOT/RDF/RFilterBase.hxx" +#include <numeric> // std::accumulate using namespace ROOT::Detail::RDF; @@ -19,10 +19,8 @@ RFilterBase::RFilterBase(RLoopManager *implPtr, std::string_view name, const uns : RNodeBase(implPtr), fLastResult(nSlots), fAccepted(nSlots), fRejected(nSlots), fName(name), fNSlots(nSlots), fCustomColumns(customColumns) {} -RFilterBase::~RFilterBase() -{ - fLoopManager->Deregister(this); -} +// outlined to pin virtual table +RFilterBase::~RFilterBase() {} bool RFilterBase::HasName() const { diff --git a/tree/dataframe/src/RRangeBase.cxx b/tree/dataframe/src/RRangeBase.cxx index 345b6939e742c105367886b2e358b55377df22c8..07ada8effc7f8c264991cf1ee664483f7783773f 100644 --- a/tree/dataframe/src/RRangeBase.cxx +++ b/tree/dataframe/src/RRangeBase.cxx @@ -8,7 +8,6 @@ * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ -#include "ROOT/RDF/RLoopManager.hxx" #include "ROOT/RDF/RRangeBase.hxx" using ROOT::Detail::RDF::RRangeBase; @@ -25,7 +24,5 @@ void RRangeBase::ResetCounters() fHasStopped = false; } -RRangeBase::~RRangeBase() -{ - fLoopManager->Deregister(this); -} +// outlined to pin virtual table +RRangeBase::~RRangeBase() { }