diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2016-10-07T17·43+0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2016-10-07T17·43+0200 |
commit | 844219f36450e94268da3f60e93efdf67055355c (patch) | |
tree | 7ea4421730697cf9118c7525c62498b0080e316e /src/libstore | |
parent | c663b84573edee2c5ece78f4ee269be73ac3ca35 (diff) |
Store::queryValidPaths(): Use async queryPathInfo()
This allows the binary cache substituter to pipeline requests.
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/store-api.cc | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index a830ae5bbd0c..b6ac1c3b987e 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; + }; - for (auto & path : paths) - if (isValidPath(path)) valid.insert(path); + Sync<State> state_(State{paths.size(), PathSet()}); - return valid; + std::condition_variable wakeup; + + for (auto & path : paths) + queryPathInfo(path, + [path, &state_, &wakeup](ref<ValidPathInfo> 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(); + }); + + while (true) { + auto state(state_.lock()); + if (!state->left) { + if (state->exc) std::rethrow_exception(state->exc); + return state->valid; + } + state.wait(wakeup); + } } |