From 844219f36450e94268da3f60e93efdf67055355c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 7 Oct 2016 19:43:36 +0200 Subject: [PATCH] Store::queryValidPaths(): Use async queryPathInfo() This allows the binary cache substituter to pipeline requests. --- src/libstore/store-api.cc | 41 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index a830ae5bb..b6ac1c3b9 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -363,12 +363,47 @@ void Store::queryPathInfo(const Path & storePath, PathSet Store::queryValidPaths(const PathSet & paths) { - PathSet valid; + struct State + { + size_t left; + PathSet valid; + std::exception_ptr exc; + }; + + Sync state_(State{paths.size(), PathSet()}); + + std::condition_variable wakeup; for (auto & path : paths) - if (isValidPath(path)) valid.insert(path); + queryPathInfo(path, + [path, &state_, &wakeup](ref info) { + auto state(state_.lock()); + state->valid.insert(path); + assert(state->left); + if (!--state->left) + wakeup.notify_one(); + }, + [path, &state_, &wakeup](std::exception_ptr exc) { + auto state(state_.lock()); + try { + std::rethrow_exception(exc); + } catch (InvalidPath &) { + } catch (...) { + state->exc = exc; + } + assert(state->left); + if (!--state->left) + wakeup.notify_one(); + }); - return valid; + while (true) { + auto state(state_.lock()); + if (!state->left) { + if (state->exc) std::rethrow_exception(state->exc); + return state->valid; + } + state.wait(wakeup); + } }