diff options
Diffstat (limited to '')
-rw-r--r-- | src/OSSupport/IsThread.cpp | 172 |
1 files changed, 57 insertions, 115 deletions
diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 1a436623a..9c62c89bf 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -5,49 +5,40 @@ // This class will eventually suupersede the old cThread class #include "Globals.h" - #include "IsThread.h" -// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: #if defined(_MSC_VER) && defined(_DEBUG) -// -// Usage: SetThreadName (-1, "MainThread"); -// - -// Code adapted from MSDN: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + // Code adapted from MSDN: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx -const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push, 8) -typedef struct tagTHREADNAME_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. -} THREADNAME_INFO; -#pragma pack(pop) - -static void SetThreadName(DWORD dwThreadID, const char * threadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); - } - __except (EXCEPTION_EXECUTE_HANDLER) + 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 && _DEBUG @@ -57,13 +48,9 @@ static void SetThreadName(DWORD dwThreadID, const char * threadName) //////////////////////////////////////////////////////////////////////////////// // cIsThread: -cIsThread::cIsThread(const AString & iThreadName) : +cIsThread::cIsThread(const AString & a_ThreadName) : m_ShouldTerminate(false), - m_ThreadName(iThreadName), - #ifdef _WIN32 - m_ThreadID(0), - #endif - m_Handle(NULL_HANDLE) + m_ThreadName(a_ThreadName) { } @@ -83,35 +70,24 @@ cIsThread::~cIsThread() bool cIsThread::Start(void) { - ASSERT(m_Handle == NULL_HANDLE); // Has already started one thread? - #ifdef _WIN32 - // Create the thread suspended, so that the mHandle variable is valid in the thread procedure - m_ThreadID = 0; - m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &m_ThreadID); - if (m_Handle == NULL) + try + { + m_Thread = std::thread(&cIsThread::Execute, this); + + #if defined (_MSC_VER) && defined(_DEBUG) + if (!m_ThreadName.empty()) { - LOGERROR("ERROR: Could not create thread \"%s\", GLE = %u!", m_ThreadName.c_str(), (unsigned)GetLastError()); - return false; + SetThreadName(&m_Thread, m_ThreadName.c_str()); } - ResumeThread(m_Handle); - - #if defined(_DEBUG) && defined(_MSC_VER) - // Thread naming is available only in MSVC - if (!m_ThreadName.empty()) - { - SetThreadName(m_ThreadID, m_ThreadName.c_str()); - } - #endif // _DEBUG and _MSC_VER - - #else // _WIN32 - if (pthread_create(&m_Handle, NULL, thrExecute, this)) - { - LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str()); - return false; - } - #endif // else _WIN32 + #endif - return true; + return true; + } + catch (std::system_error & a_Exception) + { + LOGERROR("cIsThread::Wait (std::thread) error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.what()); + return false; + } } @@ -120,10 +96,6 @@ bool cIsThread::Start(void) void cIsThread::Stop(void) { - if (m_Handle == NULL_HANDLE) - { - return; - } m_ShouldTerminate = true; Wait(); } @@ -134,59 +106,29 @@ void cIsThread::Stop(void) bool cIsThread::Wait(void) { - if (m_Handle == NULL_HANDLE) - { - return true; - } - #ifdef LOGD // ProtoProxy doesn't have LOGD LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); #endif // LOGD - - #ifdef _WIN32 - int res = WaitForSingleObject(m_Handle, INFINITE); - m_Handle = NULL; - - #ifdef LOGD // ProtoProxy doesn't have LOGD - LOGD("Thread %s finished", m_ThreadName.c_str()); - #endif // LOGD - - return (res == WAIT_OBJECT_0); - #else // _WIN32 - int res = pthread_join(m_Handle, NULL); - m_Handle = NULL_HANDLE; - - #ifdef LOGD // ProtoProxy doesn't have LOGD - LOGD("Thread %s finished", m_ThreadName.c_str()); - #endif // LOGD - - return (res == 0); - #endif // else _WIN32 -} - - - + if (m_Thread.joinable()) + { + try + { + m_Thread.join(); + return true; + } + catch (std::system_error & a_Exception) + { + LOGERROR("cIsThread::Wait (std::thread) error %i: could not join thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.what()); + return false; + } + } -unsigned long cIsThread::GetCurrentID(void) -{ - #ifdef _WIN32 - return (unsigned long) GetCurrentThreadId(); - #else - return (unsigned long) pthread_self(); + #ifdef LOGD // ProtoProxy doesn't have LOGD + LOGD("Thread %s finished", m_ThreadName.c_str()); #endif -} - - - -bool cIsThread::IsCurrentThread(void) const -{ - #ifdef _WIN32 - return (GetCurrentThreadId() == m_ThreadID); - #else - return (m_Handle == pthread_self()); - #endif + return true; } |