diff options
Diffstat (limited to '')
-rw-r--r-- | src/OSSupport/IsThread.cpp | 121 |
1 files changed, 60 insertions, 61 deletions
diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index a79fee9c6..28ed327f1 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -32,62 +32,58 @@ cIsThread::~cIsThread() -void cIsThread::DoExecute(void) +void cIsThread::Start(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 */ + // Initialize the thread: + m_Thread = std::thread(&cIsThread::Entrypoint, this); -#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) + // Notify the thread that initialization is complete and it can run its code safely: + m_Initialisation.Set(); +} - 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<const ULONG_PTR *>(&Name)); - } - __except (EXCEPTION_EXECUTE_HANDLER) + + + +void cIsThread::Stop(void) +{ + m_ShouldTerminate = true; + { + LOGD("Waiting for the %s thread to finish", m_ThreadName.c_str()); + if (m_Thread.joinable()) { + m_Thread.join(); } + LOGD("The %s thread finished", m_ThreadName.c_str()); } -#endif - - m_evtStart.Wait(); - Execute(); + m_ShouldTerminate = false; } -bool cIsThread::Start(void) +void cIsThread::Entrypoint(void) { - try - { - // Initialize the thread: - m_Thread = std::thread(&cIsThread::DoExecute, this); + // Apply thread naming: + SetThreadName(); - // Notify the thread that initialization is complete and it can run its code safely: - m_evtStart.Set(); + // Wait for initialisation: + m_Initialisation.Wait(); - return true; + try + { + Execute(); } - catch (const std::system_error & a_Exception) + catch (const std::exception & Oops) { - LOGERROR("cIsThread::Start error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); - return false; + LOGERROR("Thread %s faulted with standard exception: %s", m_ThreadName.c_str(), Oops.what()); + std::abort(); + } + catch (...) + { + LOGERROR("Thread %s faulted with unknown exception!", m_ThreadName.c_str()); + std::abort(); } } @@ -95,34 +91,37 @@ bool cIsThread::Start(void) -void cIsThread::Stop(void) +void cIsThread::SetThreadName() const { - m_ShouldTerminate = true; - Wait(); - m_ShouldTerminate = false; -} - +#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 */ + if (m_ThreadName.empty()) + { + return; + } +#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) + const DWORD NAME_EXCEPTION = 0x406D1388; + const THREADNAME_INFO Name = { 0x1000, m_ThreadName.c_str(), -1, 0 }; -bool cIsThread::Wait(void) -{ - LOGD("Waiting for the %s thread to finish", m_ThreadName.c_str()); - if (m_Thread.joinable()) + __try { - try - { - m_Thread.join(); - return true; - } - catch (const std::system_error & a_Exception) - { - 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; - } + RaiseException(NAME_EXCEPTION, 0, sizeof(Name) / sizeof(ULONG_PTR), reinterpret_cast<const ULONG_PTR *>(&Name)); } - - LOGD("The %s thread finished", m_ThreadName.c_str()); - return true; + __except (EXCEPTION_EXECUTE_HANDLER) + { + } +#endif } |