rewrite InitApartment and protect callers from (the rest of the) exceptions

Initializing COM by calling `winrt::init_apartment()` would always cause
stack unwinding *in practice*, which is suboptimal at best, and even using
`apartment_type::single_threaded` still would require exception filtering
*just in case*.
This commit is contained in:
mjk 2021-03-20 14:30:22 +00:00 committed by LAGonauta
parent c855d5e7cb
commit f1bcb6604f
2 changed files with 16 additions and 18 deletions

View file

@ -15,7 +15,7 @@
#define NOEXCEPT
#endif
EXTERN gboolean winrt_InitApartment();
EXTERN gboolean winrt_InitApartment() NOEXCEPT;
EXTERN char* winrt_windows_ui_notifications_toast_notification_manager_GetTemplateContent(winrtWindowsUINotificationsToastTemplateType type) NOEXCEPT;
#undef EXTERN

View file

@ -1,28 +1,26 @@
#include <iostream>
#include "gobject/winrt-private.h"
#include "converter.hpp"
#include "ginvoke.hpp"
gboolean winrt_InitApartment()
#include <windows.h>
static void ImplInitApartment()
{
try
const auto res = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (FAILED(res))
{
winrt::init_apartment();
return true;
}
catch(const winrt::hresult_error& e)
{
auto message = wsview_to_char(e.message());
std::cerr << message << '\n';
g_free(message);
if (e.code() == -2147417850 /* RPC_E_CHANGED_MODE */) // harmless
{
return true;
if (res == RPC_E_CHANGED_MODE) // seems harmless
g_info("attempted to change COM apartment mode of thread %" PRIu32,
::GetCurrentThreadId());
else
winrt::throw_hresult(res);
}
}
return false;
gboolean winrt_InitApartment() noexcept
{
return g_try_invoke0(ImplInitApartment).has_value();
}
static char* ImplGetTemplateContent(winrtWindowsUINotificationsToastTemplateType type)