| 43 | namespace ftl { |
| 44 | |
| 45 | static void SetThreadName(HANDLE handle, const char *threadName) { |
| 46 | const int bufLen = 128; |
| 47 | WCHAR bufWide[bufLen]; |
| 48 | |
| 49 | mbstowcs(bufWide, threadName, bufLen); |
| 50 | bufWide[bufLen - 1] = '\0'; |
| 51 | |
| 52 | // We can't call directly call "SetThreadDescription()" ( |
| 53 | // https://msdn.microsoft.com/en-us/library/windows/desktop/mt774976(v=vs.85).aspx ) here, as that would result in a vague DLL load |
| 54 | // failure at launch, on any PC running Windows older than 10.0.14393. Luckily, we can work around this crash, and provide all the |
| 55 | // benefits of "SetThreadDescription()", by manually poking into the local "kernel32.dll". |
| 56 | HMODULE hMod = ::GetModuleHandleW(L"kernel32.dll"); |
| 57 | if (hMod) { |
| 58 | using SetThreadDescriptionPtr_t = HRESULT(WINAPI *)(_In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription); |
| 59 | |
| 60 | SetThreadDescriptionPtr_t funcPtr = reinterpret_cast<SetThreadDescriptionPtr_t>(::GetProcAddress(hMod, "SetThreadDescription")); |
| 61 | if (funcPtr != nullptr) { |
| 62 | funcPtr(handle, bufWide); |
| 63 | } else { |
| 64 | // Failed to assign thread name. This requires Windows 10 Creators Update 2017, or newer, to have |
| 65 | // thread names associated with debugging, profiling, and crash dumps |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | # pragma warning(pop) |
| 70 | |
| 71 | bool CreateThread(size_t stackSize, ThreadStartRoutine startRoutine, void *arg, const char *name, ThreadType *returnThread) { |