From f5ca973762e9384ea5ebfe99be1aa07e6f604ede Mon Sep 17 00:00:00 2001 From: Autumn McKee Date: Thu, 9 Jul 2026 17:21:58 +0200 Subject: [PATCH 1/3] Add discard support for LifetimeHolder --- .../Core/include/Framework/DataAllocator.h | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Framework/Core/include/Framework/DataAllocator.h b/Framework/Core/include/Framework/DataAllocator.h index 104e418cbcd19..f1b5b16b89d40 100644 --- a/Framework/Core/include/Framework/DataAllocator.h +++ b/Framework/Core/include/Framework/DataAllocator.h @@ -115,8 +115,28 @@ struct LifetimeHolder { // invoke the callback early (e.g. for the Product<> case) void release() { - if (ptr && callback) { - callback(*ptr); + if (ptr) { + auto* released = ptr; + ptr = nullptr; + auto releaseCallback = std::move(callback); + if (releaseCallback) { + try { + releaseCallback(*released); + } catch (...) { + delete released; + throw; + } + } + delete released; + } + } + + // Delete the owned object without invoking the release callback. This is used + // when a partially filled object must be abandoned. + void discard() + { + if (ptr) { + callback = nullptr; delete ptr; ptr = nullptr; } From 46b5a2ce21994bab720fed7fd31c370751198bd8 Mon Sep 17 00:00:00 2001 From: Autumn McKee Date: Thu, 9 Jul 2026 18:47:42 +0200 Subject: [PATCH 2/3] Use early return, let callbacks handle exceptions --- .../Core/include/Framework/DataAllocator.h | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Framework/Core/include/Framework/DataAllocator.h b/Framework/Core/include/Framework/DataAllocator.h index f1b5b16b89d40..0a6ac891e4f58 100644 --- a/Framework/Core/include/Framework/DataAllocator.h +++ b/Framework/Core/include/Framework/DataAllocator.h @@ -115,31 +115,30 @@ struct LifetimeHolder { // invoke the callback early (e.g. for the Product<> case) void release() { - if (ptr) { - auto* released = ptr; - ptr = nullptr; - auto releaseCallback = std::move(callback); - if (releaseCallback) { - try { - releaseCallback(*released); - } catch (...) { - delete released; - throw; - } - } - delete released; + if (!ptr) { + return; + } + + std::unique_ptr released{ptr}; + ptr = nullptr; + auto releaseCallback = std::move(callback); + if (!releaseCallback) { + return; } + releaseCallback(*released); } // Delete the owned object without invoking the release callback. This is used // when a partially filled object must be abandoned. void discard() { - if (ptr) { - callback = nullptr; - delete ptr; - ptr = nullptr; + if (!ptr) { + return; } + + callback = nullptr; + delete ptr; + ptr = nullptr; } }; From 12e8ce423e6bdc60e03d352f201b6629c029be99 Mon Sep 17 00:00:00 2001 From: Autumn McKee Date: Mon, 13 Jul 2026 13:51:08 +0200 Subject: [PATCH 3/3] Release builder through its LifetimeHolder in ASoA cursor test --- Framework/Core/test/test_ASoA.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/test/test_ASoA.cxx b/Framework/Core/test/test_ASoA.cxx index 48cfb277acc5c..d96304bd3bce2 100644 --- a/Framework/Core/test/test_ASoA.cxx +++ b/Framework/Core/test/test_ASoA.cxx @@ -1420,5 +1420,5 @@ TEST_CASE("TestWritingCursorLastIndexAndReserve") auto table = builder->finalize(); REQUIRE(table->num_rows() == 5); REQUIRE(table->num_columns() == 2); - delete builder; + cursor.release(); }