This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
[PATCH] cygwin_internal methods to get/set thread name
- From: Mark Geisert <mark at maxrnd dot com>
- To: cygwin-patches at cygwin dot com
- Cc: Mark Geisert <mark at maxrnd dot com>
- Date: Wed, 20 Dec 2017 00:08:32 -0800
- Subject: [PATCH] cygwin_internal methods to get/set thread name
- Authentication-results: sourceware.org; auth=none
Add support to cygwin_internal() for setting a cygthread name and getting or setting a pthread name. Also add support for getting the internal i/o handle for a given file descriptor.
---
winsup/cygwin/cygthread.cc | 40 +++++++++++++++++++++++++++++++--
winsup/cygwin/cygthread.h | 1 +
winsup/cygwin/external.cc | 45 ++++++++++++++++++++++++++++++++++++--
winsup/cygwin/include/sys/cygwin.h | 6 +++++
4 files changed, 88 insertions(+), 4 deletions(-)
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index 4404e4a19..35eb48241 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -231,7 +231,7 @@ cygthread::create ()
h = htobe;
}
-/* Return the symbolic name of the current thread for debugging.
+/* Return the symbolic name of the given (or current) thread for debugging.
*/
const char *
cygthread::name (DWORD tid)
@@ -256,12 +256,48 @@ cygthread::name (DWORD tid)
res = "main";
else
{
- __small_sprintf (_my_tls.locals.unknown_thread_name, "unknown (%y)", tid);
+ /* courtesy: if tid==current thread is a pthread return its name */
+ int status = EINVAL;
+ if (tid == GetCurrentThreadId ())
+ status = pthread_getname_np (pthread_self (),
+ (char *) &_my_tls.locals.unknown_thread_name,
+ (size_t) sizeof (_my_tls.locals.unknown_thread_name));
+ if (status)
+ __small_sprintf (_my_tls.locals.unknown_thread_name,
+ "unknown (%y)", tid);
res = _my_tls.locals.unknown_thread_name;
}
return res;
}
+/* Set the symbolic name of the given (or current) thread for debugging.
+ */
+int
+cygthread::setname (DWORD tid, const char *name)
+{
+ int i;
+ char *oldname;
+
+ if (!tid)
+ tid = GetCurrentThreadId ();
+
+ for (i = 0; i < (int) NTHREADS; i++)
+ if (threads[i].id == tid)
+ {
+ oldname = (char *) threads[i].__name;
+ break;
+ }
+
+ if (i >= (int) NTHREADS)
+ return ESRCH;
+
+ threads[i].__name = strdup (name);
+ if (oldname)
+ free (oldname);
+
+ return 0;
+}
+
cygthread::operator
HANDLE ()
{
diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h
index f3b0bf00d..016d5ca8f 100644
--- a/winsup/cygwin/cygthread.h
+++ b/winsup/cygwin/cygthread.h
@@ -36,6 +36,7 @@ class cygthread
static DWORD WINAPI simplestub (VOID *);
static DWORD main_thread_id;
static const char *name (DWORD = 0);
+ static int setname (DWORD = 0, const char *name = NULL);
void __reg2 callfunc (bool) __attribute__ ((noinline, ));
void auto_release () {func = NULL;}
void release (bool);
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 3a9130efd..bfe112f2c 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -223,8 +223,41 @@ cygwin_internal (cygwin_getinfo_types t, ...)
case CW_SETTHREADNAME:
{
- set_errno (ENOSYS);
- res = 0;
+ DWORD tid = va_arg (arg, DWORD);
+ char *name = va_arg (arg, char *);
+
+ int status = cygthread::setname (tid, name);
+ if (status > 0)
+ set_errno (status);
+ else
+ res = 0;
+ }
+ break;
+
+ case CW_GET_PTHREADNAME:
+ {
+ pthread_t ptid = va_arg (arg, pthread_t);
+ char *buf = va_arg (arg, char *);
+ size_t buflen = va_arg (arg, size_t);
+
+ int status = pthread_getname_np (ptid, buf, buflen);
+ if (status > 0)
+ set_errno (status);
+ else
+ res = 0;
+ }
+ break;
+
+ case CW_SET_PTHREADNAME:
+ {
+ pthread_t ptid = va_arg (arg, pthread_t);
+ char *name = va_arg (arg, char *);
+
+ int status = pthread_setname_np (ptid, name);
+ if (status > 0)
+ set_errno (status);
+ else
+ res = 0;
}
break;
@@ -710,6 +743,14 @@ cygwin_internal (cygwin_getinfo_types t, ...)
}
break;
+ case CW_GET_IO_HANDLE_FROM_FD:
+ {
+ int fd = va_arg(arg, int);
+ fhandler_base *fh = cygheap->fdtab[fd];
+ res = (uintptr_t) (fh->get_io_handle ());
+ }
+ break;
+
default:
set_errno (ENOSYS);
}
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index c5da87c65..741e7d62d 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -158,6 +158,9 @@ typedef enum
CW_GETNSS_GRP_SRC,
CW_EXCEPTION_RECORD_FROM_SIGINFO_T,
CW_CYGHEAP_PROFTHR_ALL,
+ CW_GET_PTHREADNAME,
+ CW_SET_PTHREADNAME,
+ CW_GET_IO_HANDLE_FROM_FD,
} cygwin_getinfo_types;
#define CW_LOCK_PINFO CW_LOCK_PINFO
@@ -220,6 +223,9 @@ typedef enum
#define CW_GETNSS_GRP_SRC CW_GETNSS_GRP_SRC
#define CW_EXCEPTION_RECORD_FROM_SIGINFO_T CW_EXCEPTION_RECORD_FROM_SIGINFO_T
#define CW_CYGHEAP_PROFTHR_ALL CW_CYGHEAP_PROFTHR_ALL
+#define CW_GET_PTHREADNAME CW_GET_PTHREADNAME
+#define CW_SET_PTHREADNAME CW_SET_PTHREADNAME
+#define CW_GET_IO_HANDLE_FROM_FD CW_GET_IO_HANDLE_FROM_FD
/* Token type for CW_SET_EXTERNAL_TOKEN */
enum
--
2.15.1