Setting the thread name makes it easier to debug libvirtd
when many threads are running.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virthread.c | 44 +++++++++++++++++++++++++++++++++++-----
src/util/virthread.h | 4 +++-
3 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc0449d1d8..375e6ea000 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3258,6 +3258,7 @@ virThreadCreateFull;
virThreadID;
virThreadIsSelf;
virThreadJoin;
+virThreadMaxName;
virThreadSelf;
virThreadSelfID;
diff --git a/src/util/virthread.c b/src/util/virthread.c
index cdc5cab604..750e8d5655 100644
--- a/src/util/virthread.c
+++ b/src/util/virthread.c
@@ -175,23 +175,57 @@ void virCondBroadcast(virCondPtr c)
struct virThreadArgs {
virThreadFunc func;
- const char *funcName;
+ char *name;
bool worker;
void *opaque;
};
+size_t virThreadMaxName(void)
+{
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ return 63;
+#else
+# ifdef __linux__
+ return 15;
+# else
+ return 0; /* unlimited */
+# endif
+#endif
+}
+
static void *virThreadHelper(void *data)
{
struct virThreadArgs *args = data;
struct virThreadArgs local = *args;
+ g_autofree char *thname = NULL;
+ size_t maxname = virThreadMaxName();
/* Free args early, rather than tying it up during the entire thread. */
VIR_FREE(args);
if (local.worker)
- virThreadJobSetWorker(local.funcName);
+ virThreadJobSetWorker(local.name);
else
- virThreadJobSet(local.funcName);
+ virThreadJobSet(local.name);
+
+ if (maxname) {
+ thname = g_strndup(local.name, maxname);
+ } else {
+ thname = g_strdup(local.name);
+ }
+ g_free(local.name);
+
+#if defined(__linux__) || defined(WIN32)
+ pthread_setname_np(pthread_self(), thname);
+#else
+# ifdef __FreeBSD__
+ pthread_set_name_np(pthread_self(), thname);
+# else
+# ifdef __APPLE__
+ pthread_setname_np(thname);
+# endif
+# endif
+#endif
local.func(local.opaque);
@@ -204,7 +238,7 @@ static void *virThreadHelper(void *data)
int virThreadCreateFull(virThreadPtr thread,
bool joinable,
virThreadFunc func,
- const char *funcName,
+ const char *name,
bool worker,
void *opaque)
{
@@ -221,7 +255,7 @@ int virThreadCreateFull(virThreadPtr thread,
}
args->func = func;
- args->funcName = funcName;
+ args->name = g_strdup(name);
args->worker = worker;
args->opaque = opaque;
diff --git a/src/util/virthread.h b/src/util/virthread.h
index a7960e444a..c227951ddd 100644
--- a/src/util/virthread.h
+++ b/src/util/virthread.h
@@ -90,13 +90,15 @@ typedef void (*virThreadFunc)(void *opaque);
int virThreadCreateFull(virThreadPtr thread,
bool joinable,
virThreadFunc func,
- const char *funcName,
+ const char *name,
bool worker,
void *opaque) G_GNUC_WARN_UNUSED_RESULT;
void virThreadSelf(virThreadPtr thread);
bool virThreadIsSelf(virThreadPtr thread);
void virThreadJoin(virThreadPtr thread);
+size_t virThreadMaxName(void);
+
/* This API is *NOT* for general use. It exists solely as a stub
* for integration with libselinux AVC callbacks */
void virThreadCancel(virThreadPtr thread);
--
2.24.1