diff options
author | Vincent Ambo <mail@tazj.in> | 2022-05-18T15·39+0200 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2022-05-19T14·08+0000 |
commit | d127f9bd0e7b9b2e0df2de8a2227f77c0907468d (patch) | |
tree | 68455040d88b8e0c2817601db88ede450873ff8e /third_party/nix/src/libutil/pool.hh | |
parent | c85291c602ac666421627d6934ebc6d5be1b93e1 (diff) |
chore(3p/nix): unvendor tvix 0.1 r/4098
Nothing is using this now, and we'll likely never pick this up again, but we learned a lot in the process. Every now and then this breaks in some bizarre way on channel bumps and it's just a waste of time to maintain that. Change-Id: Idcf2f5acd4ca7070ce18d7149cbfc0d967dc0a44 Reviewed-on: https://cl.tvl.fyi/c/depot/+/5632 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: lukegb <lukegb@tvl.fyi> Autosubmit: tazjin <tazjin@tvl.su>
Diffstat (limited to 'third_party/nix/src/libutil/pool.hh')
-rw-r--r-- | third_party/nix/src/libutil/pool.hh | 176 |
1 files changed, 0 insertions, 176 deletions
diff --git a/third_party/nix/src/libutil/pool.hh b/third_party/nix/src/libutil/pool.hh deleted file mode 100644 index b5c3c4b5c43f..000000000000 --- a/third_party/nix/src/libutil/pool.hh +++ /dev/null @@ -1,176 +0,0 @@ -#pragma once - -#include <cassert> -#include <functional> -#include <limits> -#include <list> -#include <memory> - -#include "libutil/ref.hh" -#include "libutil/sync.hh" - -namespace nix { - -/* This template class implements a simple pool manager of resources - of some type R, such as database connections. It is used as - follows: - - class Connection { ... }; - - Pool<Connection> pool; - - { - auto conn(pool.get()); - conn->exec("select ..."); - } - - Here, the Connection object referenced by ‘conn’ is automatically - returned to the pool when ‘conn’ goes out of scope. -*/ - -template <class R> -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. */ - using Validator = std::function<bool(const ref<R>&)>; - - private: - Factory factory; - Validator validator; - - struct State { - size_t inUse = 0; - size_t max; - std::vector<ref<R>> idle; - }; - - Sync<State> state; - - std::condition_variable wakeup; - - public: - explicit Pool( - size_t max = std::numeric_limits<size_t>::max(), - 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; - } - - void incCapacity() { - auto state_(state.lock()); - state_->max++; - /* we could wakeup here, but this is only used when we're - * about to nest Pool usages, and we want to save the slot for - * the nested use if we can - */ - } - - void decCapacity() { - auto state_(state.lock()); - state_->max--; - } - - ~Pool() { - auto state_(state.lock()); - assert(!state_->inUse); - state_->max = 0; - state_->idle.clear(); - } - - class Handle { - private: - Pool& pool; - std::shared_ptr<R> r; - bool bad = false; - - friend Pool; - - 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() { - if (!r) { - return; - } - { - auto state_(pool.state.lock()); - if (!bad) { - state_->idle.push_back(ref<R>(r)); - } - assert(state_->inUse); - state_->inUse--; - } - pool.wakeup.notify_one(); - } - - R* operator->() { return &*r; } - R& operator*() { return *r; } - - void markBad() { bad = true; } - }; - - Handle get() { - { - auto state_(state.lock()); - - /* If we're over the maximum number of instance, we need - to wait until a slot becomes available. */ - while (state_->idle.empty() && state_->inUse >= state_->max) { - state_.wait(wakeup); - } - - while (!state_->idle.empty()) { - auto p = state_->idle.back(); - state_->idle.pop_back(); - if (validator(p)) { - state_->inUse++; - return Handle(*this, p); - } - } - - state_->inUse++; - } - - /* We need to create a new instance. Because that might take a - while, we don't hold the lock in the meantime. */ - try { - Handle h(*this, factory()); - return h; - } catch (...) { - auto state_(state.lock()); - state_->inUse--; - wakeup.notify_one(); - throw; - } - } - - size_t count() { - auto state_(state.lock()); - return state_->idle.size() + state_->inUse; - } - - size_t capacity() { return state.lock()->max; } - - void flushBad() { - auto state_(state.lock()); - std::vector<ref<R>> left; - for (auto& p : state_->idle) { - if (validator(p)) { - left.push_back(p); - } - } - std::swap(state_->idle, left); - } -}; - -} // namespace nix |