aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/pool.hh
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-21 23:50:10 +0100
committereldritch horrors <pennae@lix.systems>2024-03-31 15:46:01 +0000
commitf402c45cfa7d683fb90824cd6f6809184ed88225 (patch)
treea9a4a0f90b429b2756ece8a70ba201b4da152fcc /src/libutil/pool.hh
parent73507a716761241ca38d35fb6a873c43967c8139 (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/pool.hh')
-rw-r--r--src/libutil/pool.hh29
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; }