-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Problem
Currently, when a coroutine awaits another operation, control flows directly to the bottom-most coroutine with no opportunity for the caller to interpose logic between suspension points. This makes it impossible to implement patterns like:
- Timeouts (cancel operation after time limit)
- Progress monitoring (check operation state periodically)
- Cooperative cancellation (check stop conditions between steps)
Proposed Solution
Add proxy_context - a scoped, immovable context type that allows a supervisor coroutine to regain control between an operation's suspension points.
API
class proxy_context : public context {
public:
explicit proxy_context(context& parent);
// Immovable - must not escape supervisor's scope
proxy_context(proxy_context&&) = delete;
proxy_context& operator=(proxy_context&&) = delete;
// Not copyable
proxy_context(proxy_context const&) = delete;
proxy_context& operator=(proxy_context const&) = delete;
};Usage Example
template<typename T>
future<T> with_timeout(context& ctx,
future<result> operation,
std::chrono::milliseconds limit)
{
std::atomic<bool> timed_out{false};
auto timer = arm_timer(limit, [&]{
timed_out = true;
ctx.unblock();
});
proxy_context proxy(ctx);
auto op = operation(proxy);
while (!op.done() && !timed_out) {
op.resume(); // Run proxy operation
if (!op.done() && !timed_out) {
co_await std::suspend_always{};
}
}
if (timed_out) {
throw timeout_error{};
}
co_return op.result();
}Note that the 2nd parameter is a future, but should be a generic callable. That
way the future can be called using the proxy context and not the original
context.
Key Properties
- Scoped lifetime - Supervising coroutine creates
proxy_contexton its stack frame, ensuring memory safety through RAII - Execution interposition - Supervising coroutine regains control after each suspension point in the proxy operation
- State delegation - Blocking operations (io, sync, etc.) delegate to parent context for scheduler visibility
- Authority to intervene - Supervising coroutine can inspect state and cancel operation between execution segments
- Zero allocation overhead - Hot path (coroutine frame allocation) requires no branches or checks
Benefits
- Enables timeout implementations without scheduler modifications
- Generic primitive for monitoring/controlling subordinate operations
- Foundation for future patterns: retry limits, resource bounds, progress tracking
- Maintains "minimal prescription, maximum control" philosophy
Implementation Notes
proxy_contextuses remaining stack space from parent context- All state transitions (block/unblock) redirect to parent (original) context
- Scheduler only sees original context, not proxy contexts
- Memory loan is scoped - automatically returned when
proxy_context's frame
exits
Metadata
Metadata
Assignees
Labels
No labels