From 5123850db075b69272700b32314dc9b04e0b43b3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 28 Mar 2021 13:34:57 +0100 Subject: Fix Windows XP to 7 compatibility (#5167) * Partially reverts 01a4e696b * Unify thread names - Remove use of GetThreadId API --- src/OSSupport/IsThread.cpp | 82 ++++++++++++++++++----------------------- src/OSSupport/IsThread.h | 2 +- src/OSSupport/NetworkLookup.cpp | 2 +- 3 files changed, 37 insertions(+), 49 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 4190acb26..a79fee9c6 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -2,7 +2,6 @@ // IsThread.cpp // Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread. -// This class will eventually suupersede the old cThread class #include "Globals.h" #include "IsThread.h" @@ -11,46 +10,12 @@ -#if defined(_MSC_VER) && !defined(NDEBUG) - // Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - - const DWORD MS_VC_EXCEPTION = 0x406D1388; - #pragma pack(push, 8) - struct THREADNAME_INFO - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1 = caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - }; - #pragma pack(pop) - - /** Sets the name of a thread with the specified ID - (When in MSVC, the debugger provides "thread naming" by catching special exceptions) - */ - static void SetThreadName(std::thread * a_Thread, const char * a_ThreadName) - { - THREADNAME_INFO info { 0x1000, a_ThreadName, GetThreadId(a_Thread->native_handle()), 0 }; - __try - { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - } -#endif // _MSC_VER && !NDEBUG - - - - - //////////////////////////////////////////////////////////////////////////////// // cIsThread: -cIsThread::cIsThread(const AString & a_ThreadName) : +cIsThread::cIsThread(AString && a_ThreadName) : m_ShouldTerminate(false), - m_ThreadName(a_ThreadName) + m_ThreadName(std::move(a_ThreadName)) { } @@ -69,6 +34,36 @@ cIsThread::~cIsThread() void cIsThread::DoExecute(void) { +#if defined(_MSC_VER) && !defined(NDEBUG) + /* Sets the name of this thread. + (When in MSVC, the debugger provides "thread naming" by catching special exceptions) + Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ + +#pragma pack(push, 8) + struct THREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1 = caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + }; +#pragma pack(pop) + + if (!m_ThreadName.empty()) + { + const DWORD NAME_EXCEPTION = 0x406D1388; + const THREADNAME_INFO Name = { 0x1000, m_ThreadName.c_str(), -1, 0 }; + + __try + { + RaiseException(NAME_EXCEPTION, 0, sizeof(Name) / sizeof(ULONG_PTR), reinterpret_cast(&Name)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + } +#endif + m_evtStart.Wait(); Execute(); } @@ -84,13 +79,6 @@ bool cIsThread::Start(void) // Initialize the thread: m_Thread = std::thread(&cIsThread::DoExecute, this); - #if defined(_MSC_VER) && !defined(NDEBUG) - if (!m_ThreadName.empty()) - { - SetThreadName(&m_Thread, m_ThreadName.c_str()); - } - #endif - // Notify the thread that initialization is complete and it can run its code safely: m_evtStart.Set(); @@ -120,7 +108,7 @@ void cIsThread::Stop(void) bool cIsThread::Wait(void) { - LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); + LOGD("Waiting for the %s thread to finish", m_ThreadName.c_str()); if (m_Thread.joinable()) { try @@ -130,11 +118,11 @@ bool cIsThread::Wait(void) } catch (const std::system_error & a_Exception) { - LOGERROR("%s error %i: could not join thread %s; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); + LOGERROR("%s error %i: could not join the %s thread; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); return false; } } - LOGD("Thread %s finished", m_ThreadName.c_str()); + LOGD("The %s thread finished", m_ThreadName.c_str()); return true; } diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index d882dbf8a..6a515a6de 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -32,7 +32,7 @@ protected: std::atomic m_ShouldTerminate; public: - cIsThread(const AString & a_ThreadName); + cIsThread(AString && a_ThreadName); virtual ~cIsThread(); /** Starts the thread; returns without waiting for the actual start. */ diff --git a/src/OSSupport/NetworkLookup.cpp b/src/OSSupport/NetworkLookup.cpp index 5cd7ecfc4..8a0e54015 100644 --- a/src/OSSupport/NetworkLookup.cpp +++ b/src/OSSupport/NetworkLookup.cpp @@ -11,7 +11,7 @@ cNetworkLookup::cNetworkLookup() : - cIsThread("NetworkLookup") + cIsThread("Network Lookup Executor") { } -- cgit v1.2.3