From 8075541d82d05347321d35b9934ccee5f82142f4 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Thu, 21 Mar 2024 23:50:10 +0100 Subject: [PATCH] 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,6 +108,19 @@ public: Handle(Pool & pool, std::shared_ptr r) : pool(pool), r(r) { } + void drop(bool stillValid) + { + { + auto state_(pool.state.lock()); + 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(); } @@ -115,15 +128,13 @@ public: ~Handle() { - if (!r) return; - { - auto state_(pool.state.lock()); - if (!std::uncaught_exceptions()) - state_->idle.push_back(ref(r)); - assert(state_->inUse); - state_->inUse--; - } - pool.wakeup.notify_one(); + if (r) + drop(std::uncaught_exceptions() == 0); + } + + void release() + { + drop(true); } R * operator -> () { return &*r; }