libutil: add async base header

currently this header only contains TRY_AWAIT, and it's public version
LIX_TRY_AWAIT. the former is for use in our cpp files only, the latter
may be used anywhere. we don't expose TRY_AWAIT unconditionally due to
it not being namespaced according to usual rules of macro naming, i.e.
exposing it may litter user macro namespaces unnecessarily. hiding our
internal version is achieved using a new define that's not set through
pkg-config or other means. (we could also add a private header that we
simply do not install, but that gets rather messy rather very quickly)

Change-Id: I372b1a414487dd03cfbfc620b3148a6c6e56ca3f
This commit is contained in:
eldritch horrors
2025-01-23 17:21:23 +00:00
parent 91fe1e0217
commit 020ea8c8fc
6 changed files with 48 additions and 7 deletions
+6 -5
View File
@@ -1,4 +1,5 @@
#include "lix/libstore/build/derivation-goal.hh"
#include "lix/libutil/async.hh"
#include "lix/libutil/file-system.hh"
#include "lix/libstore/build/hook-instance.hh"
#include "lix/libstore/build/worker.hh"
@@ -176,7 +177,7 @@ try {
co_return co_await loadDerivation();
}
(co_await waitForGoals(worker.goalFactory().makePathSubstitutionGoal(drvPath))).value();
TRY_AWAIT(waitForGoals(worker.goalFactory().makePathSubstitutionGoal(drvPath)));
co_return co_await loadDerivation();
} catch (...) {
co_return result::current_exception();
@@ -302,7 +303,7 @@ try {
}
if (!dependencies.empty()) { /* to prevent hang (no wake-up event) */
(co_await waitForGoals(dependencies.releaseAsArray())).value();
TRY_AWAIT(waitForGoals(dependencies.releaseAsArray()));
}
co_return co_await outputsSubstitutionTried();
} catch (...) {
@@ -447,7 +448,7 @@ try {
}
if (!dependencies.empty()) {/* to prevent hang (no wake-up event) */
(co_await waitForGoals(dependencies.releaseAsArray())).value();
TRY_AWAIT(waitForGoals(dependencies.releaseAsArray()));
}
co_return co_await inputsRealised();
} catch (...) {
@@ -513,7 +514,7 @@ try {
co_return done(BuildResult::AlreadyValid, assertPathValidity());
}
(co_await waitForGoals(dependencies.releaseAsArray())).value();
TRY_AWAIT(waitForGoals(dependencies.releaseAsArray()));
co_return co_await closureRepaired();
} catch (...) {
co_return result::current_exception();
@@ -618,7 +619,7 @@ try {
pathResolved, wantedOutputs, buildMode);
resolvedDrvGoal = dependency.first;
(co_await waitForGoals(std::move(dependency))).value();
TRY_AWAIT(waitForGoals(std::move(dependency)));
co_return co_await resolvedFinished();
}
@@ -1,5 +1,6 @@
#include "lix/libstore/build/drv-output-substitution-goal.hh"
#include "lix/libstore/build-result.hh"
#include "lix/libutil/async.hh"
#include "lix/libutil/finally.hh"
#include "lix/libstore/build/worker.hh"
#include "lix/libstore/build/substitution-goal.hh"
@@ -126,7 +127,7 @@ try {
dependencies.add(worker.goalFactory().makePathSubstitutionGoal(outputInfo->outPath));
if (!dependencies.empty()) {
(co_await waitForGoals(dependencies.releaseAsArray())).value();
TRY_AWAIT(waitForGoals(dependencies.releaseAsArray()));
}
co_return co_await outPathValid();
} catch (...) {
+2 -1
View File
@@ -1,6 +1,7 @@
#include "lix/libstore/build/worker.hh"
#include "lix/libstore/build/substitution-goal.hh"
#include "lix/libstore/nar-info.hh"
#include "lix/libutil/async.hh"
#include "lix/libutil/signals.hh"
#include "lix/libutil/finally.hh"
#include <boost/outcome/try.hpp>
@@ -166,7 +167,7 @@ try {
dependencies.add(worker.goalFactory().makePathSubstitutionGoal(i));
if (!dependencies.empty()) {/* to prevent hang (no wake-up event) */
(co_await waitForGoals(dependencies.releaseAsArray())).value();
TRY_AWAIT(waitForGoals(dependencies.releaseAsArray()));
}
co_return co_await referencesValid();
} catch (...) {
+28
View File
@@ -0,0 +1,28 @@
#pragma once
///@file
#include "lix/libutil/result.hh"
namespace nix {
namespace detail {
inline void materializeResult(Result<void> r)
{
r.value();
}
template<typename T>
inline T materializeResult(Result<T> r)
{
return std::move(r.value());
}
}
}
// force materialization of the value. result::value() returns only an rvalue reference
// and is thus unsuitable for use in e.g. range for without materialization. ideally we
// would wrap the expression in `auto()`, but apple clang fails when given `auto(void)`
#define LIX_TRY_AWAIT(...) (::nix::detail::materializeResult(co_await (__VA_ARGS__)))
#if LIX_UR_COMPILER_UWU
# define TRY_AWAIT LIX_TRY_AWAIT
#endif
+1
View File
@@ -55,6 +55,7 @@ libutil_headers = files(
'args/root.hh',
'args.hh',
'async-collect.hh',
'async.hh',
'async-semaphore.hh',
'backed-string-view.hh',
'box_ptr.hh',
+9
View File
@@ -138,6 +138,15 @@ endif
cxx = meson.get_compiler('cpp')
# tag define to tell us we are compiling lix itself and can thus make
# non-namespaced aliases of a utility defines visible. this spares us
# writing LIX_TRY_AWAIT, LIX_RUN_ASYNC_IN, and others in our own code
# without being forced to hide the headers we take these defines from
add_project_arguments(
'-DLIX_UR_COMPILER_UWU',
language : 'cpp',
)
# clangd breaks when GCC is using precompiled headers lmao
# https://git.lix.systems/lix-project/lix/issues/374