Advanced - enter()/exit()#

When tmc::enter(Executor) is called, the task will be resumed on Executor, and it will return a scope object that captures the current executor and priority. This can be used to later exit() the scope and return to the previous executor and priority.

// assume we start on the cpu executor here
auto scope = co_await tmc::enter(other_exec);
// do something on the other executor
co_await scope.exit();
// we are back on the cpu executor now, with our original priority

Further customizations can be applied to the enter() and exit() calls.

The enter() awaitable supports with_priority(). The exit() awaitable supports resume_on() and with_priority().

Examples:

// assume we start on the cpu executor here, at priority 0
auto scope = co_await tmc::enter(other_exec).with_priority(1);
// we are now running on other_exec, at priority 1
co_await scope.exit().resume_on(third_exec).with_priority(2);
// we are now running on third_exec, at priority 2

API Reference#

template<typename E>
inline aw_ex_scope_enter<E> tmc::enter(E &Executor)#

Returns an awaitable that suspends the current task and resumes it in the target executor’s context. It may be resumed on a different thread than the one calling enter(). This is idempotent, and is similar in effect to co_await resume_on(exec);, but additionally saves the current priority in the case of an exec that does not use priority internally, such as ex_braid or ex_cpu.

template<typename E>
inline aw_ex_scope_enter<E> tmc::enter(E *Executor)#

A convenience function identical to tmc::enter(E& exec)

template<typename E>
class aw_ex_scope_enter : private tmc::detail::AwaitTagNoGroupAsIs#

The awaitable type returned by tmc::enter().

Public Functions

inline bool await_ready()#

Always suspends.

TMC_FORCE_INLINE inline std::coroutine_handle await_suspend(std::coroutine_handle<> Outer)#

Switch this task to the target executor.

inline aw_ex_scope_exit<E> await_resume()#

Returns an aw_ex_scope_exit with an exit() method that can be called to exit the executor, and resume this task back on its original executor.

inline aw_ex_scope_enter &with_priority(size_t Priority)#

When awaited, the outer coroutine will be resumed with the provided priority.

template<typename E>
class aw_ex_scope_exit : private tmc::detail::AwaitTagNoGroupAsIs#

The awaitable type returned by co_await tmc::enter(). Call co_await this.exit() to exit the executor scope.

Public Functions

inline aw_ex_scope_exit &&exit()#

Returns an awaitable that can be co_await’ed to exit the executor scope. This is idempotent. (Not strictly necessary - you can just co_await std::move(*this); directly - but makes code a bit easier to understand.)

inline bool await_ready()#

Always suspends.

TMC_FORCE_INLINE inline void await_suspend(std::coroutine_handle<> Outer)#

Post this task to the continuation executor.

inline void await_resume()#

Restores the original priority. Only necessary in case of resuming onto an executor where post() doesn’t respect priority, such as ex_asio.

inline aw_ex_scope_exit &resume_on(tmc::ex_any *Executor)#

When awaited, the outer coroutine will be resumed on the provided executor.

template<typename Exec>
inline aw_ex_scope_exit &resume_on(Exec &Executor)#

When awaited, the outer coroutine will be resumed on the provided executor.

template<typename Exec>
inline aw_ex_scope_exit &resume_on(Exec *Executor)#

When awaited, the outer coroutine will be resumed on the provided executor.

inline aw_ex_scope_exit &with_priority(size_t Priority)#

When awaited, the outer coroutine will be resumed with the provided priority.