mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Initialize the Windows COM library on all threads
Use threading model `COINIT_APARTMENTTHREADED` on threads that own a window (the main client thread) and `COINIT_MULTITHREADED` on all other threads. Add assertions to ensure that the COM library is initialized successfully and only once per thread. References: - https://learn.microsoft.com/en-us/windows/win32/learnwin32/initializing-the-com-library - https://learn.microsoft.com/en-us/windows/win32/com/single-threaded-apartments - https://learn.microsoft.com/en-us/windows/win32/com/multithreaded-apartments Yet another attempt at solving #5744.
This commit is contained in:
parent
65a3cdff02
commit
4bb549b68e
|
@ -719,6 +719,9 @@ static unsigned long __stdcall thread_run(void *user)
|
|||
#error not implemented
|
||||
#endif
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
CWindowsComLifecycle WindowsComLifecycle(false);
|
||||
#endif
|
||||
struct THREAD_RUN *data = (THREAD_RUN *)user;
|
||||
void (*threadfunc)(void *) = data->threadfunc;
|
||||
void *u = data->u;
|
||||
|
@ -4252,9 +4255,12 @@ int net_socket_read_wait(NETSOCKET sock, std::chrono::nanoseconds nanoseconds)
|
|||
}
|
||||
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
CWindowsComLifecycle::CWindowsComLifecycle()
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/learnwin32/initializing-the-com-library
|
||||
CWindowsComLifecycle::CWindowsComLifecycle(bool HasWindow)
|
||||
{
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
HRESULT result = CoInitializeEx(NULL, (HasWindow ? COINIT_APARTMENTTHREADED : COINIT_MULTITHREADED) | COINIT_DISABLE_OLE1DDE);
|
||||
dbg_assert(result != S_FALSE, "COM library already initialized on this thread");
|
||||
dbg_assert(result == S_OK, "COM library initialization failed");
|
||||
}
|
||||
CWindowsComLifecycle::~CWindowsComLifecycle()
|
||||
{
|
||||
|
|
|
@ -2563,11 +2563,14 @@ public:
|
|||
/**
|
||||
* This is a RAII wrapper to initialize/uninitialize the Windows COM library,
|
||||
* which may be necessary for using the open_file and open_link functions.
|
||||
* Must be used on every thread. It's automatically used on threads created
|
||||
* with thread_init. Pass true to the constructor on threads that own a
|
||||
* window (i.e. pump a message queue).
|
||||
*/
|
||||
class CWindowsComLifecycle
|
||||
{
|
||||
public:
|
||||
CWindowsComLifecycle();
|
||||
CWindowsComLifecycle(bool HasWindow);
|
||||
~CWindowsComLifecycle();
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -4574,7 +4574,7 @@ int main(int argc, const char **argv)
|
|||
#if defined(CONF_PLATFORM_ANDROID)
|
||||
const char **argv = const_cast<const char **>(argv2);
|
||||
#elif defined(CONF_FAMILY_WINDOWS)
|
||||
CWindowsComLifecycle WindowsComLifecycle;
|
||||
CWindowsComLifecycle WindowsComLifecycle(true);
|
||||
#endif
|
||||
CCmdlineFix CmdlineFix(&argc, &argv);
|
||||
bool Silent = false;
|
||||
|
|
|
@ -62,6 +62,10 @@ int main(int argc, const char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
CWindowsComLifecycle WindowsComLifecycle(false);
|
||||
#endif
|
||||
|
||||
std::vector<std::shared_ptr<ILogger>> vpLoggers;
|
||||
#if defined(CONF_PLATFORM_ANDROID)
|
||||
vpLoggers.push_back(std::shared_ptr<ILogger>(log_logger_android()));
|
||||
|
|
Loading…
Reference in a new issue