63 std::vector<ref<R>> idle;
64 std::list<kj::Own<kj::CrossThreadPromiseFulfiller<void>>> waiters;
68 for (
auto & waiter : waiters) {
79 Pool(
size_t max = std::numeric_limits<size_t>::max(),
80 const Factory & factory = []() {
return make_ref<R>(); },
81 const Validator & validator = [](ref<R> r) {
return true; })
83 , validator(validator)
85 auto state_(state.lock());
91 auto state_(state.lock());
101 auto state_(state.lock());
107 auto state_(state.lock());
108 assert(!state_->inUse);
110 state_->idle.clear();
117 std::shared_ptr<R> r;
122 Handle(Pool & pool, std::shared_ptr<R> r) : pool(pool), r(r) { }
125 Handle(Handle && h) : pool(h.pool), r(h.r) { h.r.reset(); }
127 Handle(
const Handle & l) =
delete;
133 auto state_(pool.state.lock());
135 state_->idle.push_back(ref<R>::unsafeFromPtr(r));
136 assert(state_->inUse);
142 R * operator -> () {
return &*r; }
143 R & operator * () {
return *r; }
145 void markBad() { bad =
true; }
151 auto state_(state.lock());
158 kj::Promise<Result<std::optional<Handle>>> tryGet()
160 auto state_(state.
lock());
164 if (state_->idle.empty() && state_->inUse >= state_->max) {
165 auto pfp = kj::newPromiseAndCrossThreadFulfiller<void>();
166 state_->waiters.push_back(std::move(pfp.fulfiller));
167 return pfp.promise.then([
this] {
return tryGet(); });
170 while (!state_->idle.empty()) {
171 auto p = state_->idle.back();
172 state_->idle.pop_back();
175 return {
Handle(*
this, p)};
180 return {std::nullopt};
182 return {result::current_exception()};
186 kj::Promise<Result<Handle>> get()
188 if (
auto existing = LIX_TRY_AWAIT(tryGet())) {
189 co_return std::move(*existing);
195 Handle h(*
this, factory());
202 co_return result::current_exception();
207 auto state_(state.lock());
208 return state_->idle.size() + state_->inUse;
213 return state.lock()->max;