Stack usage reduction in apartment switching, and lifetime fixes #1272
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The big deal here is that we fix
co_await apartment_contextso that it consumes no stack[1] if you are already in the destination context. This is a big win for loops that do apartment switching.To do this,
impl::resume_apartmentnow returnstrueif it wants the caller to resume the coroutine synchronously, rather than doing it directly. If the caller isawait_suspend, then it can propagate that result to the coroutine infrastructure and avoid stack build-up.Fixed a lifetime issue in
apartment_awaiter, which copied the context too soon. It needs to copy it in theawait_suspend, because the coroutine is to resume synchronously in the new apartment, which under the old code would destruct the context whileawait_suspendwas still using it. This shifts a refcount update from one place to another, so no net change.We no longer need to extend the lifetime of the
IAsyncActionnow that we detect and defer synchronous resumption. This deletes a refcount update.[1] Older builds of MSVC have code generation issues for
bool await_suspend, so we deftly avoid them here, in the same way we avoided them forco_await IAsyncAction. (Though the existing code in many awaiters such asfinal_suspend_awaiterstill usebool await_suspend, so maybe it's okay to assume MSVC 16.11 or later?)