6#include "lix/libutil/signals.hh"
8#include <kj/async-io.h>
11#include <source_location>
17 static inline thread_local AsyncContext * current =
nullptr;
19 kj::AsyncIoProvider & provider;
20 kj::UnixEventPort & unixEventPort;
22 explicit AsyncContext(kj::AsyncIoContext & aio)
23 : provider(*aio.provider)
24 , unixEventPort(aio.unixEventPort)
26 assert(current ==
nullptr);
35 KJ_DISALLOW_COPY_AND_MOVE(AsyncContext);
40 kj::AsyncIoContext kj;
43 AsyncIoRoot() : kj(kj::setupAsyncIo()), context(kj) {}
44 KJ_DISALLOW_COPY_AND_MOVE(AsyncIoRoot);
47 auto blockOn(kj::Promise<T> && promise);
52 assert(AsyncContext::current !=
nullptr);
53 return *AsyncContext::current;
57inline void materializeResult(Result<void> r)
63inline T materializeResult(Result<T> r)
65 return std::move(r.value());
74T runAsyncUnwrap(Result<T> t)
76 return std::move(t).value();
79auto runAsyncInNewThread(std::invocable<AsyncIoRoot &>
auto fn)
81 auto future = std::async(std::launch::async, [&] {
84 if constexpr (!std::is_void_v<
decltype(fn(aioRoot))>) {
85 return runAsyncUnwrap(fn(aioRoot));
95#define LIX_RUN_ASYNC_IN_NEW_THREAD(...) \
96 ::nix::detail::runAsyncInNewThread([&](AsyncIoRoot & AIOROOT) { \
97 return AIOROOT.blockOn(__VA_ARGS__); \
100#define LIX_TRY_AWAIT_CONTEXT(ctx, ...) \
102 auto _lix_awaited = co_await (__VA_ARGS__); \
103 if (_lix_awaited.has_error()) { \
105 _lix_awaited.value(); \
106 } catch (::nix::BaseException & e) { \
107 e.addAsyncTrace(::std::source_location::current(), ctx()); \
109 } catch (::std::exception & e) { \
110 ::nix::ForeignException fe(e); \
111 fe.addAsyncTrace(::std::source_location::current(), ctx()); \
115 ::nix::detail::materializeResult(std::move(_lix_awaited)); \
124static constexpr std::optional<std::string> lixAsyncTaskContext()
132#define LIX_TRY_AWAIT(...) LIX_TRY_AWAIT_CONTEXT(lixAsyncTaskContext, __VA_ARGS__)
134#if LIX_UR_COMPILER_UWU
135#define RUN_ASYNC_IN_NEW_THREAD LIX_RUN_ASYNC_IN_NEW_THREAD
136#define TRY_AWAIT LIX_TRY_AWAIT
140inline auto nix::AsyncIoRoot::blockOn(kj::Promise<T> && promise)
142 return detail::runAsyncUnwrap(promise.wait(kj.waitScope));
This file defines two main structs/classes used in nix error handling.