I was experiencing occasional crashes in C++/WinRT’s resume_foreground function when it tries to resume execution on a dispatcher queue. Here’s a simplified version of that function:
auto resume_foreground(DispatcherQueue const& dispatcher)
bool m_queued = false; bool await_ready()
Today is a puzzle you can you can try to solve with the information you’ve learned about C++ coroutines and C++/WinRT.
C++/WinRT uses the IContextCallback interface to remember the context that initiated a co_await operation, so it can resume execution in the original apartment when the co_await completes.
So you’re following along Kenny Kerr’s blog and you get to the part where he uses co_await on a time duration:
co_await 5s; so you try it:
using namespace std::chrono;
} and you get the error message
no callable ‘await_resume’
At the start of this series, I noted that there are three steps in obtaining an awaiter for an awaitable object. The first two were marked “We’re not read to talk about this yet.”
Well, now we’re ready to talk about one of them.
Gdbserver is a program that allows you to remotely debug applications running on Linux. It is especially useful in embedded scenarios where your target system may not have the resources to run the full gdb.
Visual Studio 2019 version 16.5 Preview 1 enables remote debugging of CMake projects with gdbserver.
You try to co_await something and get the error message
no callable ‘await_resume’ (or ‘await_ready’ or ‘await_suspend’) function found for type ‘Expression’
What does this mean?
Recall how the compiler generates code for co_await: calculate x
obtain awaiter co_await if (!awaiter.await_ready())
save state for resumption
return to caller [Invoking the handle resumes execution here]
restore state after resumption
result = awaiter.await_resume();
Docker containers provide a consistent development environment for building, testing, and deployment. The virtualized OS, file system, environment settings, libraries, and other dependencies are all encapsulated and shipped as one image that can be shared between developers and machines. This is especially useful for C++ cross-platform developers because you can target a container that runs a different operating system than the one on your development machine.
At the start of this series, I gave the basic idea for how the compiler generates code for co_await, but I left out some details for expository simplicity. There are some mysterious steps called “We’re not ready to talk about this step yet.”
The C++/WinRT library provides an awaiter for Windows Runtime asynchronous activities. Those asynchronous activities are represented by IAsyncAction, IAsyncOperation, and progress versions of the above. The C++/WinRT-provided awaiter resumes execution of the caller in the same COM apartment that awaited the activity.
So far, we’ve been looking at the basics of awaitable objects. Even though we barely know anything beyond await_suspend, we already know enough to allow us to start diving deeper.
It is frequently the case that you need your awaiter to interact with something outside the C++ standard library.