System: Move COM init to common code

This commit is contained in:
Stenzek 2024-04-25 12:56:02 +10:00
parent 425235fd31
commit 7548113afd
No known key found for this signature in database
5 changed files with 25 additions and 18 deletions

View file

@ -72,6 +72,7 @@ Log_SetChannel(System);
#ifdef _WIN32 #ifdef _WIN32
#include "common/windows_headers.h" #include "common/windows_headers.h"
#include <mmsystem.h> #include <mmsystem.h>
#include <objbase.h>
#endif #endif
#ifdef ENABLE_DISCORD_PRESENCE #ifdef ENABLE_DISCORD_PRESENCE
@ -253,8 +254,20 @@ static TinyString GetTimestampStringForFileName()
return TinyString::from_format("{:%Y-%m-%d-%H-%M-%S}", fmt::localtime(std::time(nullptr))); return TinyString::from_format("{:%Y-%m-%d-%H-%M-%S}", fmt::localtime(std::time(nullptr)));
} }
bool System::Internal::ProcessStartup() bool System::Internal::CPUThreadInitialize()
{ {
#ifdef _WIN32
// On Win32, we have a bunch of things which use COM (e.g. SDL, Cubeb, etc).
// We need to initialize COM first, before anything else does, because otherwise they might
// initialize it in single-threaded/apartment mode, which can't be changed to multithreaded.
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr))
{
Host::ReportErrorAsync("Error", fmt::format("CoInitializeEx() failed: {:08X}", static_cast<unsigned>(hr)));
return false;
}
#endif
if (!Bus::AllocateMemory()) if (!Bus::AllocateMemory())
return false; return false;
@ -279,7 +292,7 @@ bool System::Internal::ProcessStartup()
return true; return true;
} }
void System::Internal::ProcessShutdown() void System::Internal::CPUThreadShutdown()
{ {
#ifdef ENABLE_DISCORD_PRESENCE #ifdef ENABLE_DISCORD_PRESENCE
ShutdownDiscordPresence(); ShutdownDiscordPresence();
@ -291,6 +304,10 @@ void System::Internal::ProcessShutdown()
CPU::CodeCache::ProcessShutdown(); CPU::CodeCache::ProcessShutdown();
Bus::ReleaseMemory(); Bus::ReleaseMemory();
#ifdef _WIN32
CoUninitialize();
#endif
} }
void System::Internal::IdlePollUpdate() void System::Internal::IdlePollUpdate()

View file

@ -490,10 +490,10 @@ void UpdateDiscordPresence(bool update_session_time);
namespace Internal { namespace Internal {
/// Called on process startup. /// Called on process startup.
bool ProcessStartup(); bool CPUThreadInitialize();
/// Called on process shutdown. /// Called on process shutdown.
void ProcessShutdown(); void CPUThreadShutdown();
/// Polls input, updates subsystems which are present while paused/inactive. /// Polls input, updates subsystems which are present while paused/inactive.
void IdlePollUpdate(); void IdlePollUpdate();

View file

@ -1603,7 +1603,7 @@ void EmuThread::run()
m_started_semaphore.release(); m_started_semaphore.release();
// input source setup must happen on emu thread // input source setup must happen on emu thread
if (!System::Internal::ProcessStartup()) if (!System::Internal::CPUThreadInitialize())
{ {
moveToThread(m_ui_thread); moveToThread(m_ui_thread);
return; return;
@ -1645,7 +1645,7 @@ void EmuThread::run()
System::ShutdownSystem(false); System::ShutdownSystem(false);
destroyBackgroundControllerPollTimer(); destroyBackgroundControllerPollTimer();
System::Internal::ProcessShutdown(); System::Internal::CPUThreadShutdown();
// move back to UI thread // move back to UI thread
moveToThread(m_ui_thread); moveToThread(m_ui_thread);

View file

@ -657,7 +657,7 @@ int main(int argc, char* argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!System::Internal::ProcessStartup()) if (!System::Internal::CPUThreadInitialize())
return EXIT_FAILURE; return EXIT_FAILURE;
RegTestHost::HookSignals(); RegTestHost::HookSignals();
@ -689,6 +689,6 @@ int main(int argc, char* argv[])
result = 0; result = 0;
cleanup: cleanup:
System::Internal::ProcessShutdown(); System::Internal::CPUThreadShutdown();
return result; return result;
} }

View file

@ -123,16 +123,6 @@ void CubebAudioStream::DestroyContextAndStream()
bool CubebAudioStream::Initialize(const char* driver_name, const char* device_name, Error* error) bool CubebAudioStream::Initialize(const char* driver_name, const char* device_name, Error* error)
{ {
#ifdef _WIN32
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
m_com_initialized_by_us = SUCCEEDED(hr);
if (FAILED(hr) && hr != RPC_E_CHANGED_MODE)
{
Error::SetHResult(error, "CoInitializeEx() failed: ", hr);
return false;
}
#endif
cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback); cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback);
int rv = int rv =