Nix 2.35.2
Nix, the purely functional package manager; unstable internal interfaces
Loading...
Searching...
No Matches
goal-impl.hh
1#pragma once
2#include "nix/store/build/goal.hh"
3#include "nix/store/build/worker.hh"
4
5namespace nix {
6
7template<typename T>
8auto Goal::promise_type::await_transform(AsyncCallback<T> && ac)
9{
10 struct Awaiter
11 {
12 fun<void(Callback<T>)> fn;
13 std::shared_ptr<std::promise<T>> promise;
14
15 bool await_ready()
16 {
17 return false;
18 }
19
20 void await_suspend(handle_type h)
21 {
22 auto goal = h.promise().goal;
23 promise = std::make_shared<std::promise<T>>();
24
25 fn(Callback<T>([promise = promise,
26 maybeWaker = goal->worker.getCrossThreadWaker(),
27 goalWeak = goal->weak_from_this()](std::future<T> res) {
28 try {
29 promise->set_value(res.get());
30 } catch (...) {
31 promise->set_exception(std::current_exception());
32 }
33
34 /* The Worker might have already died (and the waker with it) by
35 the time the callback fired. */
36 if (auto waker = maybeWaker.lock())
37 waker->enqueue(goalWeak);
38 }));
39
40 goal->worker.waitForCompletion(goal->shared_from_this());
41 }
42
43 T await_resume()
44 {
45 return promise->get_future().get();
46 }
47 };
48
49 return Awaiter{.fn = std::move(ac.fn)};
50}
51
52} // namespace nix