Core/Thread: Make use of SetThreadDescription if possible (win32)

This commit is contained in:
Lynix 2020-01-06 15:35:48 +01:00
parent c378ad26a9
commit c73d08af9b
3 changed files with 29 additions and 11 deletions

View File

@ -215,6 +215,7 @@ Nazara Engine:
- Added EmptyStream class, useful to measure how many bytes some writing operations will take
- SegmentCollider2D: Add support for neighbors (aka "ghost vertices"), allowing to prevent seams collisions
- ⚠ OBJLoader flips UV by default, fixing a lot of models UV
- On Windows, Thread::Set(Current)Name now uses `SetThreadDescription` Win32 function if possible instead of triggering a debugger exception. MinGW builds will use this if available too.
Nazara Development Kit:
- Added ImageWidget (#139)

View File

@ -11,6 +11,9 @@
namespace Nz
{
// Windows 10, version 1607 brought SetThreadDescription in order to name a thread
using SetThreadDescriptionFunc = HRESULT(WINAPI*)(HANDLE hThread, PCWSTR lpThreadDescription);
#ifdef NAZARA_COMPILER_MSVC
namespace
{
@ -50,12 +53,12 @@ namespace Nz
void ThreadImpl::SetName(const Nz::String& name)
{
SetThreadName(m_threadId, name.GetConstBuffer());
SetThreadName(m_handle, name);
}
void ThreadImpl::SetCurrentName(const Nz::String& name)
{
SetThreadName(::GetCurrentThreadId(), name.GetConstBuffer());
SetThreadName(::GetCurrentThread(), name);
}
void ThreadImpl::Sleep(UInt32 time)
@ -63,9 +66,12 @@ namespace Nz
::Sleep(time);
}
void ThreadImpl::SetThreadName(DWORD threadId, const char* threadName)
void ThreadImpl::RaiseThreadNameException(DWORD threadId, const char* threadName)
{
#ifdef NAZARA_COMPILER_MSVC
if (!::IsDebuggerPresent())
return;
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
@ -86,10 +92,20 @@ namespace Nz
}
#pragma warning(pop)
#else
NazaraWarning("SetThreadName on Windows is only supported with MSVC for now");
NazaraWarning("SetThreadDescription is not supported and threadname exception is only supported with MSVC");
#endif
}
void ThreadImpl::SetThreadName(HANDLE threadHandle, const Nz::String& name)
{
// Try to use SetThreadDescription if available
static SetThreadDescriptionFunc SetThreadDescription = reinterpret_cast<SetThreadDescriptionFunc>(::GetProcAddress(::GetModuleHandleW(L"Kernel32.dll"), "SetThreadDescription"));
if (SetThreadDescription)
SetThreadDescription(threadHandle, name.GetWideString().data());
else
RaiseThreadNameException(::GetThreadId(threadHandle), name.GetConstBuffer());
}
unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata)
{
Functor* func = static_cast<Functor*>(userdata);

View File

@ -30,7 +30,8 @@ namespace Nz
static void Sleep(UInt32 time);
private:
static void SetThreadName(DWORD threadId, const char* threadName);
static void RaiseThreadNameException(DWORD threadId, const char* threadName);
static void SetThreadName(HANDLE threadHandle, const Nz::String& name);
static unsigned int __stdcall ThreadProc(void* userdata);
DWORD m_threadId;