diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-02-24T10·39+0100 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-02-24T10·39+0100 |
commit | 5f862658c3f8e518fb631d0536f2b38f107970e1 (patch) | |
tree | 34a38a2405fda244f547b06c6db264f3986e1aab /src/libutil/pool.hh | |
parent | d5626bf4c14f725136f2c5b6ac8bf818627352f0 (diff) |
Remove bad daemon connections from the pool
This is necessary for long-running processes like hydra-queue-runner: if a nix-daemon worker is killed, we need to stop reusing that connection.
Diffstat (limited to 'src/libutil/pool.hh')
-rw-r--r-- | src/libutil/pool.hh | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/libutil/pool.hh b/src/libutil/pool.hh index 4b865a19389e..b75a3cbf854f 100644 --- a/src/libutil/pool.hh +++ b/src/libutil/pool.hh @@ -33,11 +33,17 @@ class Pool { public: + /* A function that produces new instances of R on demand. */ typedef std::function<ref<R>()> Factory; + /* A function that checks whether an instance of R is still + usable. Unusable instances are removed from the pool. */ + typedef std::function<bool(const ref<R> &)> Validator; + private: Factory factory; + Validator validator; struct State { @@ -53,8 +59,10 @@ private: public: Pool(size_t max = std::numeric_limits<size_t>::max, - const Factory & factory = []() { return make_ref<R>(); }) + const Factory & factory = []() { return make_ref<R>(); }, + const Validator & validator = [](ref<R> r) { return true; }) : factory(factory) + , validator(validator) { auto state_(state.lock()); state_->max = max; @@ -109,11 +117,13 @@ public: while (state_->idle.empty() && state_->inUse >= state_->max) state_.wait(wakeup); - if (!state_->idle.empty()) { + while (!state_->idle.empty()) { auto p = state_->idle.back(); state_->idle.pop_back(); - state_->inUse++; - return Handle(*this, p); + if (validator(p)) { + state_->inUse++; + return Handle(*this, p); + } } state_->inUse++; |