subj

-- 
O< ascii ribbon - stop html email! - www.asciiribbon.org
From 034016acce54ee530999f428f19ebfc61719124b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?=
 =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1...@gmail.com>
Date: Tue, 14 Apr 2015 02:22:54 +0000
Subject: [PATCH] Implement pthread_setname_np and pthread_getname_np

These should be compatible with Linux, pthreads-win32 (Linux mode) and Cygwin
implementations (but not OSX, BSD or pthreads-win32 (BSD mode)).

Based on MSDN code[1].

[1] https://msdn.microsoft.com/en-us/library/xcb2z8hs%28v=vs.71%29.aspx
---
 mingw-w64-libraries/winpthreads/include/pthread.h |   3 +
 mingw-w64-libraries/winpthreads/src/thread.c      | 129 ++++++++++++++++++++++
 mingw-w64-libraries/winpthreads/src/thread.h      |   2 +
 3 files changed, 134 insertions(+)

diff --git a/mingw-w64-libraries/winpthreads/include/pthread.h 
b/mingw-w64-libraries/winpthreads/include/pthread.h
index f63d328..355bdae 100644
--- a/mingw-w64-libraries/winpthreads/include/pthread.h
+++ b/mingw-w64-libraries/winpthreads/include/pthread.h
@@ -314,6 +314,9 @@ int       WINPTHREAD_API pthread_create_wrapper(void *args);
 int       WINPTHREAD_API pthread_create(pthread_t *th, const pthread_attr_t 
*attr, void *(* func)(void *), void *arg);
 int       WINPTHREAD_API pthread_join(pthread_t t, void **res);
 int       WINPTHREAD_API pthread_detach(pthread_t t);
+int       WINPTHREAD_API pthread_setname_np(pthread_t thread, const char 
*name);
+int       WINPTHREAD_API pthread_getname_np(pthread_t thread, char *name, 
size_t len);
+
 
 int WINPTHREAD_API pthread_rwlock_init(pthread_rwlock_t *rwlock_, const 
pthread_rwlockattr_t *attr);
 int WINPTHREAD_API pthread_rwlock_wrlock(pthread_rwlock_t *l);
diff --git a/mingw-w64-libraries/winpthreads/src/thread.c 
b/mingw-w64-libraries/winpthreads/src/thread.c
index 141faf0..5c40f12 100644
--- a/mingw-w64-libraries/winpthreads/src/thread.c
+++ b/mingw-w64-libraries/winpthreads/src/thread.c
@@ -21,6 +21,7 @@
 */
 
 #include <windows.h>
+#include <strsafe.h>
 #include <stdio.h>
 #include <malloc.h>
 #include <signal.h>
@@ -52,6 +53,60 @@ static size_t idListCnt = 0;
 static size_t idListMax = 0;
 static pthread_t idListNextId = 0;
 
+#if !defined(_MSC_VER) || defined (USE_VEH_FOR_MSC_SETTHREADNAME)
+static void *SetThreadName_VEH_handle = NULL;
+
+static LONG __stdcall
+SetThreadName_VEH (PEXCEPTION_POINTERS ExceptionInfo)
+{
+  if (ExceptionInfo->ExceptionRecord != NULL &&
+      ExceptionInfo->ExceptionRecord->ExceptionCode == 
EXCEPTION_SET_THREAD_NAME)
+    return EXCEPTION_CONTINUE_EXECUTION;
+
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+typedef 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 */
+} THREADNAME_INFO;
+
+static void
+SetThreadName (DWORD dwThreadID, LPCSTR szThreadName)
+{
+   THREADNAME_INFO info;
+   DWORD infosize;
+
+   info.dwType = 0x1000;
+   info.szName = szThreadName;
+   info.dwThreadID = dwThreadID;
+   info.dwFlags = 0;
+
+   infosize = sizeof (info) / sizeof (DWORD);
+
+#if defined(_MSC_VER) && !defined (USE_VEH_FOR_MSC_SETTHREADNAME)
+   __try
+     {
+       RaiseException (EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD *) 
&info);
+     }
+   __except (EXCEPTION_EXECUTE_HANDLER)
+     {
+     }
+#else
+   /* Without a debugger we *must* have an exception handler,
+    * otherwise raising an exception will crash the process.
+    */
+   if ((!IsDebuggerPresent ()) && (SetThreadName_VEH_handle == NULL))
+     return;
+
+   RaiseException (EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD *) &info);
+#endif
+}
+
 /* Search the list idList for an element with identifier ID.  If
    found, its associated _pthread_v pointer is returned, otherwise
    NULL.
@@ -234,6 +289,8 @@ push_pthread_mem (_pthread_v *sv)
     free (sv->keyval);
   if (sv->keyval_set)
     free (sv->keyval_set);
+  if (sv->thread_name)
+    free (sv->thread_name);
   memset (sv, 0, sizeof(struct _pthread_v));
   if (pthr_last == NULL)
     pthr_root = pthr_last = sv;
@@ -326,8 +383,22 @@ __dyn_tls_pthread (HANDLE hDllHandle, DWORD dwReason, 
LPVOID lpreserved)
 
   if (dwReason == DLL_PROCESS_DETACH)
     {
+#if !defined(_MSC_VER) || defined (USE_VEH_FOR_MSC_SETTHREADNAME)
+      if (lpreserved == NULL && SetThreadName_VEH_handle != NULL)
+        {
+          RemoveVectoredExceptionHandler (SetThreadName_VEH_handle);
+          SetThreadName_VEH_handle = NULL;
+        }
+#endif
       free_pthread_mem ();
     }
+  else if (dwReason == DLL_PROCESS_ATTACH)
+    {
+#if !defined(_MSC_VER) || defined (USE_VEH_FOR_MSC_SETTHREADNAME)
+      SetThreadName_VEH_handle = AddVectoredExceptionHandler (1, 
&SetThreadName_VEH);
+      /* Can't do anything on error anyway, check for NULL later */
+#endif
+    }
   else if (dwReason == DLL_THREAD_DETACH)
     {
       if (_pthread_tls != 0xffffffff)
@@ -1667,3 +1738,61 @@ pthread_setconcurrency (int new_level)
   return 0;
 }
 
+int
+pthread_setname_np (pthread_t thread, const char *name)
+{
+  struct _pthread_v *tv;
+  char *stored_name;
+
+  if (name == NULL)
+    return EINVAL;
+
+  tv = __pth_gpointer_locked (thread);
+  if (!tv || thread != tv->x || tv->in_cancel || tv->ended || tv->h == NULL
+      || tv->h == INVALID_HANDLE_VALUE)
+    return ESRCH;
+
+  stored_name = strdup (name);
+  if (stored_name == NULL)
+    return ENOMEM;
+
+  if (tv->thread_name != NULL)
+    free (tv->thread_name);
+
+  tv->thread_name = stored_name;
+  SetThreadName (tv->tid, name);
+  return 0;
+}
+
+int
+pthread_getname_np (pthread_t thread, char *name, size_t len)
+{
+  HRESULT result;
+  struct _pthread_v *tv;
+
+  if (name == NULL)
+    return EINVAL;
+
+  tv = __pth_gpointer_locked (thread);
+  if (!tv || thread != tv->x || tv->in_cancel || tv->ended || tv->h == NULL
+      || tv->h == INVALID_HANDLE_VALUE)
+    return ESRCH;
+
+  if (len < 1)
+    return ERANGE;
+
+  if (tv->thread_name == NULL)
+    {
+      name[0] = '\0';
+      return 0;
+    }
+
+  if (strlen (tv->thread_name) >= len)
+    return ERANGE;
+
+  result = StringCchCopyNA (name, len, tv->thread_name, len - 1);
+  if (SUCCEEDED (result))
+    return 0;
+
+  return ERANGE;
+}
diff --git a/mingw-w64-libraries/winpthreads/src/thread.h 
b/mingw-w64-libraries/winpthreads/src/thread.h
index 07cfc24..caaf058 100644
--- a/mingw-w64-libraries/winpthreads/src/thread.h
+++ b/mingw-w64-libraries/winpthreads/src/thread.h
@@ -29,6 +29,7 @@
 
 #define LIFE_THREAD 0xBAB1F00D
 #define DEAD_THREAD 0xDEADBEEF
+#define EXCEPTION_SET_THREAD_NAME ((DWORD) 0x406D1388)
 
 typedef struct _pthread_v _pthread_v;
 struct _pthread_v
@@ -48,6 +49,7 @@ struct _pthread_v
     unsigned int keymax;
     void **keyval;
     unsigned char *keyval_set;
+    char *thread_name;
     pthread_spinlock_t spin_keys;
     DWORD tid;
     int rwlc;
-- 
1.8.5.3

Attachment: 0x922360B0.asc
Description: application/pgp-keys

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to