-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
resume_agile to allow coroutine to resume in any apartment #1356
Conversation
By default, `co_await`'ing a Windows Runtime asynchronous operation resumes in the same COM apartment. We provide a way to override this behavior and resume in any apartment by wrapping the asynchronous operation in `resume_agile()`. ```cpp extern IAsyncAction Example(); // This resumes in the same apartment co_await Example(); // This resumes in any apartment co_await resume_agile(Example()); ``` The guts of the change are in `disconnect_aware_handler` which accepts a `preserve_context` template parameter, defaulting to `true`. If `false`, then we bypass the `resume_apartment()` on completion. The `false` value is provided by the `resume_agile()` function. To remove the `resume_apartment_context` from the `disconnect_aware_handler` in the case where we don't need it, I use EBO and make it a base class, so that it disappears when an empty `ignore_apartment_context` is used. While I was there, I introduced `movable_primitive<T>` which provides RAII-like functionality to scalars like integers and pointers. This allows us to simplify `disconnect_aware_handler` and `resume_apartment_context`, which previously had to override all the copy and move operations in order to reset the scalar on move. Also fix the `await_adapter.cpp` tests so they don't leak DispatcherQueues, by explicitly shutting down all the dispatcher queues we created. This required moving all the controllers to top-level so we can shut them down after the tests have completed.
Open issues:
Note that C# uses
// Don't do this.
auto later = resume_agile(Something());
co_await later; I think reference is okay because Pros/cons:
|
My vote is for free function. Our policy so far has to put these things as free functions so discoverability doesn't seem like a problem here ... resume_foreground, cancellation helpers, etc. If you want this, you know you need it, so you know where to find it. (I'm of two minds about monkeypatching via extension methods for the same reason.) Can you capture it by move, so someone who says I like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I like this idea - it gives us the best of both worlds.
|
await_adapter is not owning, it holds |
The difference is that up until now, This change introduces a way to obtain an auto oops = resume_agile(ZorpAsync());
co_await oops; |
That is a fair assessment, though one could already get an adapter without awaiting by calling the operator manually. To make this work, await_adapter and all operators would need to be changed to take ownership, not just resume_agile. |
Somebody who invokes the operator manually |
By default,
co_await
'ing a Windows Runtime asynchronous operation resumes in the same COM apartment. We provide a way to override this behavior and resume in any apartment by wrapping the asynchronous operation inresume_agile()
.The guts of the change are in
disconnect_aware_handler
which accepts apreserve_context
template parameter, defaulting totrue
. Iffalse
, then we bypass theresume_apartment()
on completion. Thefalse
value is provided by theresume_agile()
function.To remove the
resume_apartment_context
from thedisconnect_aware_handler
in the case where we don't need it, I use EBO and make it a base class, so that it disappears when an emptyignore_apartment_context
is used.While I was there, I introduced
movable_primitive<T>
which provides RAII-like functionality to scalars like integers and pointers. This allows us to simplifydisconnect_aware_handler
andresume_apartment_context
, which previously had to override all the copy and move operations in order to reset the scalar on move.Also fix the
await_adapter.cpp
tests so they don't leak DispatcherQueues, by explicitly shutting down all the dispatcher queues we created. This required moving all the controllers to top-level so we can shut them down after the tests have completed.Fixes: #1355