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
#include "common/windows_headers.h"
#include <mmsystem.h>
#include <objbase.h>
#endif
#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)));
}
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())
return false;
@ -279,7 +292,7 @@ bool System::Internal::ProcessStartup()
return true;
}
void System::Internal::ProcessShutdown()
void System::Internal::CPUThreadShutdown()
{
#ifdef ENABLE_DISCORD_PRESENCE
ShutdownDiscordPresence();
@ -291,6 +304,10 @@ void System::Internal::ProcessShutdown()
CPU::CodeCache::ProcessShutdown();
Bus::ReleaseMemory();
#ifdef _WIN32
CoUninitialize();
#endif
}
void System::Internal::IdlePollUpdate()

View File

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

View File

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

View File

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

View File

@ -123,16 +123,6 @@ void CubebAudioStream::DestroyContextAndStream()
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);
int rv =