diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8563695c32..07dee6d841 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3279,6 +3279,7 @@ virThreadCreateFull; virThreadID; virThreadIsSelf; virThreadJoin; +virThreadMaxName; virThreadSelf; virThreadSelfID; diff --git a/src/util/virthread.c b/src/util/virthread.c index cdc5cab604..40792afdc0 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); + g_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; @@ -230,7 +264,8 @@ int virThreadCreateFull(virThreadPtr thread, err = pthread_create(&thread->thread, &attr, virThreadHelper, args); if (err != 0) { - VIR_FREE(args); + g_free(args->name); + g_free(args); goto cleanup; } /* New thread owns 'args' in success case, so don't free */ 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);