diff options
author | eldritch horrors <pennae@lix.systems> | 2024-03-21 23:50:10 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-03-31 15:46:01 +0000 |
commit | f402c45cfa7d683fb90824cd6f6809184ed88225 (patch) | |
tree | a9a4a0f90b429b2756ece8a70ba201b4da152fcc /src/libutil | |
parent | 73507a716761241ca38d35fb6a873c43967c8139 (diff) |
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
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/pool.hh | 29 |
1 files 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> 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>(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; } |