From 429ff94dc55b4189bebcf1b0e6b5e8034d45095d Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 6 Jan 2025 18:56:58 +0000 Subject: [PATCH] Windows: Only deinit the thread CRT when destroying the current thread The thread termination callback can be called for other threads in the process, not just the current one, in which case we cannot call DeinitCRT. Deinitializing the CRT of another thread would be awkward so just skip that and accept the small leak for now. --- Source/Windows/ARM64EC/Module.cpp | 18 ++++++++++-------- Source/Windows/WOW64/Module.cpp | 16 +++++++++------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index a24963412..523b5bcae 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -816,20 +816,22 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) { auto* OldThreadState = CPUArea.ThreadState(); CPUArea.ThreadState() = nullptr; - { - THREAD_BASIC_INFORMATION Info; - if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { - return Err; - } + THREAD_BASIC_INFORMATION Info; + if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { + return Err; + } - const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + { std::scoped_lock Lock(ThreadCreationMutex); Threads.erase(ThreadTID); } CTX->DestroyThread(OldThreadState); - ::VirtualFree(reinterpret_cast(GetCPUArea().EmulatorStackLimit()), 0, MEM_RELEASE); - FEX::Windows::DeinitCRTThread(); + ::VirtualFree(reinterpret_cast(CPUArea.EmulatorStackLimit()), 0, MEM_RELEASE); + if (ThreadTID == GetCurrentThreadId()) { + FEX::Windows::DeinitCRTThread(); + } return STATUS_SUCCESS; } diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index ebf5f01b7..df56d2bb0 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -517,19 +517,21 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) { return; } - { - THREAD_BASIC_INFORMATION Info; - if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { - return; - } + THREAD_BASIC_INFORMATION Info; + if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { + return; + } - const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + { std::scoped_lock Lock(ThreadCreationMutex); Threads.erase(ThreadTID); } CTX->DestroyThread(TLS.ThreadState()); - FEX::Windows::DeinitCRTThread(); + if (ThreadTID == GetCurrentThreadId()) { + FEX::Windows::DeinitCRTThread(); + } } void* BTCpuGetBopCode() {