Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
nix::Goal::Co Struct Reference

#include <goal.hh>

Public Member Functions

 Co (handle_type handle)
 
void operator= (Co &&)
 
 Co (Co &&rhs)
 
bool await_ready ()
 
std::coroutine_handle await_suspend (handle_type handle)
 
void await_resume ()
 

Public Attributes

handle_type handle
 

Detailed Description

C++20 coroutine wrapper for use in goal logic. Coroutines are functions that use co_await/co_return (and co_yield, but not supported by Co).

Co is meant to be used by methods of subclasses of Goal. The main functionality provided by Co is

  • co_await Suspend{}: Suspends the goal.
  • co_await f(): Waits until f() finishes.
  • co_return f(): Tail-calls f().
  • co_return Return{}: Ends coroutine.

The idea is that you implement the goal logic using coroutines, and do the core thing a goal can do, suspension, when you have children you're waiting for. Coroutines allow you to resume the work cleanly.

Note
Brief explanation of C++20 coroutines: When you Co f(), a std::coroutine_handle<promise_type> is created, alongside its promise_type. There are suspension points at the beginning of the coroutine, at every co_await, and at the final (possibly implicit) co_return. Once suspended, you can resume the std::coroutine_handle by doing coroutine_handle.resume(). Suspension points are implemented by passing a struct to the compiler that implements await_suspend. await_suspend can either say "cancel suspension", in which case execution resumes, "suspend", in which case control is passed back to the caller of coroutine_handle.resume() or the place where the coroutine function is initially executed in the case of the initial suspension, or await_suspend can specify another coroutine to jump to, which is how tail calls are implemented.
Resources:
Todo
Allocate explicitly on stack since HALO thing doesn't really work, specifically, there's no way to uphold the requirements when trying to do tail-calls without using a trampoline AFAICT.
Todo
Support returning data natively

Member Function Documentation

◆ await_suspend()

std::coroutine_handle nix::Goal::Co::await_suspend ( handle_type handle)

When we co_await another Co-returning coroutine, we tell the caller of caller_coroutine.resume() to switch to our coroutine (handle). To make sure we return to the original coroutine, we set it as the continuation of our coroutine. In promise_type::final_awaiter we check if it's set and if so we return to it.

To explain in more understandable terms: When we co_await Co_returning_function(), this function is called on the resultant Co of the called function, and C++ automatically passes the caller in.

goal field of promise_type is also set here by copying it from the caller.

Member Data Documentation

◆ handle

handle_type nix::Goal::Co::handle

The underlying handle.


The documentation for this struct was generated from the following files: