summaryrefslogtreecommitdiffhomepage
path: root/compat
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2019-04-29 15:52:24 +0200
committerStanislaw Halik <sthalik@misaki.pl>2019-04-29 15:52:24 +0200
commitb061108a1e98ed1d1f869f4e71fe35373515b2a0 (patch)
treeeebfaa427b31a07083d863b8d13e8ec56d543971 /compat
parent00a1a3d81b82a411cd8cbdf5a480c4007b2b60bc (diff)
compat: allow naming threads for debugging
Diffstat (limited to 'compat')
-rw-r--r--compat/thread-name.cpp80
-rw-r--r--compat/thread-name.hpp6
2 files changed, 86 insertions, 0 deletions
diff --git a/compat/thread-name.cpp b/compat/thread-name.cpp
new file mode 100644
index 00000000..f74ac505
--- /dev/null
+++ b/compat/thread-name.cpp
@@ -0,0 +1,80 @@
+#ifdef _WIN32
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0501
+# endif
+# include "thread-name.hpp"
+# include <QDebug>
+# include <windows.h>
+#else
+# include <QThread>
+#endif
+
+namespace portable {
+
+#if defined _MSC_VER
+
+struct THREADNAME_INFO
+{
+ DWORD dwType; // must be 0x1000
+ LPCSTR szName; // pointer to name (in user addr space)
+ HANDLE dwThreadID; // thread ID (-1=caller thread)
+ DWORD dwFlags; // reserved for future use, must be zero
+};
+
+static inline
+void set_curthread_name_old(const QString& name_)
+{
+ QByteArray str = name_.toLocal8Bit();
+ const char* name = str.constData();
+ HANDLE curthread = GetCurrentThread();
+
+ THREADNAME_INFO info; // NOLINT(cppcoreguidelines-pro-type-member-init)
+ info.dwType = 0x1000;
+ info.szName = name;
+ info.dwThreadID = curthread;
+ info.dwFlags = 0;
+ __try
+ {
+ static_assert(sizeof(info) % sizeof(unsigned) == 0);
+ unsigned sz = sizeof(info)/sizeof(unsigned);
+ RaiseException(0x406D1388, 0, sz, (const ULONG_PTR*)&info);
+ }
+ __except (EXCEPTION_CONTINUE_EXECUTION)
+ {
+ }
+}
+
+void set_curthread_name(const QString& name)
+{
+ static_assert(sizeof(wchar_t) == sizeof(decltype(*QString().utf16())));
+
+ HMODULE module;
+ HRESULT (__stdcall *fn)(HANDLE, const wchar_t*);
+ if (GetModuleHandleExA(0, "kernel32.dll", &module) &&
+ (fn = (decltype(fn))GetProcAddress(module, "SetThreadDescription")))
+ {
+ fn(GetCurrentThread(), (const wchar_t*)name.utf16());
+ }
+ else
+ {
+ set_curthread_name_old(name);
+ }
+}
+
+#elif defined _WIN32
+
+void set_curthread_name(const QString& name)
+{
+ (void)name;
+}
+
+#else
+
+void set_curthread_name(const QString& name)
+{
+ QThread::currentThread()->setObjectName(name);
+}
+
+#endif
+
+} // ns portable
diff --git a/compat/thread-name.hpp b/compat/thread-name.hpp
new file mode 100644
index 00000000..21256003
--- /dev/null
+++ b/compat/thread-name.hpp
@@ -0,0 +1,6 @@
+#pragma once
+#include "export.hpp"
+#include <QString>
+namespace portable {
+ OTR_COMPAT_EXPORT void set_curthread_name(const QString& name);
+}