January 26th, 2023

Inside C++/WinRT: Apartment switching: Bypassing the context callback

Last time, we avoided the problem of the synchronous apartment-changing callback.

Our implementation always uses IContext­Callback::Context­Callback() to switch apartments. This is rather wasteful if we are already in the target apartment: It consumes a good amount of stack space as we call into the COM infrastructure, and then the COM infrastructure calls us back, where we then resume the coroutine, when we could have just resumed the coroutine directly without getting COM involved at all. It is not uncommon to resume a coroutine’s execution in the context you are already in (say, because the awaited-on coroutine happens to finish in the same apartment in which it started). The extra stack consumption can become a problem if you have a long chain of coroutines, or are awaiting in a loop.

To short-circuit the IContext­Callback::Context­Callback(), we can check whether we are already in the correct apartment, in which case we resume the coroutine immediately.

inline auto resume_apartment(
    com_ptr<IContextCallback> const& context,
    coroutine_handle<> handle)
{
    WINRT_ASSERT(context.valid());
    if (context ==
        capture<IContextCallback>(WINRT_IMPL_CoGetObjectContext))
    {
        handle();
    }
    else if (is_sta_thread())
    {
        resume_apartment_on_threadpool(context, handle);
    }
    else
    {
        resume_apartment_sync(context, handle);
    }
}

If the original context equals the current context, then we are already in the correct apartment, and we can just resume the coroutine immediately. Only if the contexts don’t match do we need to go through the whole IContext­Callback::Context­Callback() ritual.

Next time, we’ll try to address another source of unwanted stack build-up.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.