diff options
| author | Martin Ridgers <[email protected]> | 2021-10-15 16:04:56 +0200 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-10-15 16:04:56 +0200 |
| commit | 402dfddf62d979319038801a926809e33839e096 (patch) | |
| tree | e8a8e99c7f4718a5fcc363245cc19e16a41bea25 /zencore/thread.cpp | |
| parent | If/def around Windows-only headers (diff) | |
| parent | httpasio: Implemented support for specifying accept type via url suffix (diff) | |
| download | zen-402dfddf62d979319038801a926809e33839e096.tar.xz zen-402dfddf62d979319038801a926809e33839e096.zip | |
Merged main
Diffstat (limited to 'zencore/thread.cpp')
| -rw-r--r-- | zencore/thread.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/zencore/thread.cpp b/zencore/thread.cpp index 5aa0f2688..72b8c54f6 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -15,6 +15,61 @@ namespace zen { +#if ZEN_PLATFORM_WINDOWS +// The information on how to set the thread name comes from +// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx +const DWORD kVCThreadNameException = 0x406D1388; +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; +// The SetThreadDescription API was brought in version 1607 of Windows 10. +typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription); +// This function has try handling, so it is separated out of its caller. +void +SetNameInternal(DWORD thread_id, const char* name) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = thread_id; + info.dwFlags = 0; + __try + { + RaiseException(kVCThreadNameException, 0, sizeof(info) / sizeof(DWORD), reinterpret_cast<DWORD_PTR*>(&info)); + } + __except (EXCEPTION_CONTINUE_EXECUTION) + { + } +} +#endif + +void +SetCurrentThreadName([[maybe_unused]] std::string_view ThreadName) +{ +#if ZEN_PLATFORM_WINDOWS + // The SetThreadDescription API works even if no debugger is attached. + static auto SetThreadDescriptionFunc = + reinterpret_cast<SetThreadDescription>(::GetProcAddress(::GetModuleHandle(L"Kernel32.dll"), "SetThreadDescription")); + + if (SetThreadDescriptionFunc) + { + SetThreadDescriptionFunc(::GetCurrentThread(), Utf8ToWide(ThreadName).c_str()); + } + // The debugger needs to be around to catch the name in the exception. If + // there isn't a debugger, we are just needlessly throwing an exception. + if (!::IsDebuggerPresent()) + return; + + std::string ThreadNameZ{ThreadName}; + SetNameInternal(GetCurrentThreadId(), ThreadNameZ.c_str()); +#else +#endif +} // namespace zen + void RwLock::AcquireShared() { |