affine_awaitable

An awaitable is affine if it participates in the affine awaitable protocol by accepting a dispatcher in its await_suspend method.

Requires: C++20

Synopsis

Defined in header <boost/capy/affine.hpp>

namespace boost::capy {

template<typename A, typename D, typename P = void>
concept affine_awaitable =
    dispatcher<D, P> &&
    requires(A a, std::coroutine_handle<P> h, D const& d) {
        a.await_suspend(h, d);
    };

} // namespace boost::capy

Description

The affine awaitable protocol enables zero-overhead scheduler affinity without requiring the full sender/receiver protocol. When an awaitable is affine, it receives the caller’s dispatcher in await_suspend and uses it to resume the caller on the correct execution context.

The awaitable must use the dispatcher d to resume the caller when the operation completes. Typically this looks like return d(h); for symmetric transfer or calling d(h) before returning std::noop_coroutine().

Preconditions

  • The dispatcher d remains valid until the awaitable resumes the caller

Valid Expressions

Given:

  • a — a value of type A

  • h — a value of type std::coroutine_handle<P>

  • d — a const value of type D satisfying dispatcher<D, P>

Expression Return Type Description

a.await_ready()

bool

Return true if the operation has already completed

a.await_suspend(h, d)

(unspecified)

Suspend and start the async operation, using d for resumption

a.await_resume()

(unspecified)

Return the operation result or rethrow any exception

Example

#include <boost/capy/affine.hpp>

using boost::capy::coro;
using boost::capy::affine_awaitable;
using boost::capy::any_dispatcher;

struct my_async_op
{
    bool await_ready() const noexcept
    {
        return false;
    }

    template<typename Dispatcher>
    auto await_suspend(coro h, Dispatcher const& d)
    {
        start_async([h, &d] {
            // Operation completed, resume through dispatcher
            d(h);
        });
        return std::noop_coroutine();
    }

    int await_resume()
    {
        return result_;
    }

private:
    int result_ = 42;
};

static_assert(affine_awaitable<my_async_op, any_dispatcher>);

See Also