Skip to content

Commit da87b91

Browse files
jlaanstrakennykerr
authored andcommitted
Check for STA and NA when deciding to call directly or post a callback. (#459)
1 parent 0bab91b commit da87b91

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

strings/base_coroutine_foundation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ namespace winrt::impl
8888

8989
void await_suspend(std::experimental::coroutine_handle<> handle) const
9090
{
91-
async.Completed([handle, context = impl::sta_apartment_context()](auto&& ...)
91+
async.Completed([handle, context = impl::apartment_context()](auto&& ...)
9292
{
9393
impl::resume_apartment(context, handle);
9494
});

strings/base_coroutine_threadpool.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,16 @@ namespace winrt::impl
2121
return (0 == WINRT_CoGetApartmentType(&aptType, &aptTypeQualifier)) && ((aptType == 0 /*APTTYPE_STA*/) || (aptType == 3 /*APTTYPE_MAINSTA*/));
2222
}
2323

24-
inline auto sta_apartment_context()
24+
inline bool requires_apartment_context() noexcept
2525
{
26-
return is_sta() ? capture<IContextCallback>(WINRT_CoGetObjectContext) : nullptr;
26+
int32_t aptType;
27+
int32_t aptTypeQualifier;
28+
return (0 == WINRT_CoGetApartmentType(&aptType, &aptTypeQualifier)) && ((aptType == 0 /*APTTYPE_STA*/) || (aptType == 2 /*APTTYPE_NA*/) || (aptType == 3 /*APTTYPE_MAINSTA*/));
29+
}
30+
31+
inline auto apartment_context()
32+
{
33+
return requires_apartment_context() ? capture<IContextCallback>(WINRT_CoGetObjectContext) : nullptr;
2734
}
2835

2936
inline int32_t __stdcall resume_apartment_callback(com_callback_args* args) noexcept
@@ -32,18 +39,18 @@ namespace winrt::impl
3239
return 0;
3340
};
3441

35-
inline auto resume_apartment(com_ptr<IContextCallback> const& sta_context, std::experimental::coroutine_handle<> handle)
42+
inline auto resume_apartment(com_ptr<IContextCallback> const& context, std::experimental::coroutine_handle<> handle)
3643
{
37-
if (sta_context)
44+
if (context)
3845
{
3946
com_callback_args args{};
4047
args.data = handle.address();
4148

42-
check_hresult(sta_context->ContextCallback(resume_apartment_callback, &args, guid_of<ICallbackWithNoReentrancyToApplicationSTA>(), 5, nullptr));
49+
check_hresult(context->ContextCallback(resume_apartment_callback, &args, guid_of<ICallbackWithNoReentrancyToApplicationSTA>(), 5, nullptr));
4350
}
4451
else
4552
{
46-
if (is_sta())
53+
if (requires_apartment_context())
4754
{
4855
resume_background(handle);
4956
}
@@ -284,10 +291,10 @@ WINRT_EXPORT namespace winrt
284291

285292
void await_suspend(std::experimental::coroutine_handle<> handle) const
286293
{
287-
impl::resume_apartment(sta_context, handle);
294+
impl::resume_apartment(context, handle);
288295
}
289296

290-
com_ptr<impl::IContextCallback> sta_context = impl::sta_apartment_context();
297+
com_ptr<impl::IContextCallback> context = impl::apartment_context();
291298
};
292299

293300
[[nodiscard]] inline auto resume_after(Windows::Foundation::TimeSpan duration) noexcept

0 commit comments

Comments
 (0)