Allow resume_agile to be stored in a variable #1358
Merged
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.
resume_agile
exposes the ability to save theawait_adapter
in a variable. This was not possible withoutresume_agile
because theawait_adapter
had previously been available only viaoperator co_await
, which means that it is created only in response to an immediate attempt toco_await
it, so we knew that it would be consumed before its argument (possibly a temporary) was destructed.resume_agile
returns theawait_adapter
, and we expect people to await it immediately, but it's possible that they decide to save it in a variable and await it later. In that case, we have to record theAsync
as a value instead of a reference. We forward theresume_agile
argument into theAsync
so that it moves if given an rvalue reference, or copies if given an lvalue reference. This ensure that the common case where somebody doesco_await resume_agile(DoSomething())
, we do not incur any additional AddRefs or Releases.Now that it's possible to
co_await
theawait_adapter
twice, we have to worry aboutawait_suspend
being called twice. It had previously assumed thatsuspending
was true (since that's how it was constructed), but that is no longer valid in theresume_agile
case if somebody tries to await theresume_agile
twice. So we have to force it totrue
. (Now, the second await will fail with "illegal delegate assignment", but our failure to setsuspending
totrue
led to double-resumption, which is super-bad.)Fixes #1357