From f402c45cfa7d683fb90824cd6f6809184ed88225 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Thu, 21 Mar 2024 23:50:10 +0100 Subject: libutil: allow graceful dropping of Pool::Handle not needed yet, but returning a resource from the exception handling path that has ownership of a handle is currently not well-supported. we could also add a default constructor to Handle, but then we would also need to change the pool reference to a pointer. eventually that should be done since now resources can be swapped between pools with clever moves, but since that's not a problem yet we won't do it now. Change-Id: I26eb06581f7be34569e9e67a33da736128d167af --- src/libutil/pool.hh | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/libutil/pool.hh b/src/libutil/pool.hh index 2f6d30130..bc71083e9 100644 --- a/src/libutil/pool.hh +++ b/src/libutil/pool.hh @@ -108,22 +108,33 @@ public: Handle(Pool & pool, std::shared_ptr r) : pool(pool), r(r) { } - public: - Handle(Handle && h) : pool(h.pool), r(h.r) { h.r.reset(); } - - Handle(const Handle & l) = delete; - - ~Handle() + void drop(bool stillValid) { - if (!r) return; { auto state_(pool.state.lock()); - if (!std::uncaught_exceptions()) - state_->idle.push_back(ref(r)); + if (stillValid) + state_->idle.emplace_back(std::move(r)); assert(state_->inUse); state_->inUse--; } pool.wakeup.notify_one(); + r = nullptr; + } + + public: + Handle(Handle && h) : pool(h.pool), r(h.r) { h.r.reset(); } + + Handle(const Handle & l) = delete; + + ~Handle() + { + if (r) + drop(std::uncaught_exceptions() == 0); + } + + void release() + { + drop(true); } R * operator -> () { return &*r; } -- cgit v1.2.3