src: set the OS level thread name

Setting the thread name makes it easier to debug libvirtd
when many threads are running.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2020-02-14 10:44:01 +00:00
parent eab55b2534
commit c85256b31b
3 changed files with 46 additions and 8 deletions

View File

@ -3279,6 +3279,7 @@ virThreadCreateFull;
virThreadID;
virThreadIsSelf;
virThreadJoin;
virThreadMaxName;
virThreadSelf;
virThreadSelfID;

View File

@ -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 */

View File

@ -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);