mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
build: avoid non-portable cast of pthread_t
POSIX says pthread_t is opaque. We can't guarantee if it is scaler or a pointer, nor what size it is; and BSD differs from Linux. We've also had reports of gcc complaining on attempts to cast it, if we use a cast to the wrong type (for example, pointers have to be cast to void* or intptr_t before being narrowed; while casting a function return of scalar pthread_t to void* triggers a different warning). Give up on casts, and use unions to get at decent bits instead. And rather than futz around with figuring which 32 bits of a potentially 64-bit pointer are most likely to be unique, convert the rest of the code base to use 64-bit values when using a debug id. Based on a report by Guido Günther against kFreeBSD, but with a fix that doesn't regress commit 4d970fd29 for FreeBSD. * src/util/virthreadpthread.c (virThreadSelfID, virThreadID): Use union to get at a decent bit representation of thread_t bits. * src/util/virthread.h (virThreadSelfID, virThreadID): Alter signature. * src/util/virthreadwin32.c (virThreadSelfID, virThreadID): Likewise. * src/qemu/qemu_domain.h (qemuDomainJobObj): Alter type of owner. * src/qemu/qemu_domain.c (qemuDomainObjTransferJob) (qemuDomainObjSetJobPhase, qemuDomainObjReleaseAsyncJob) (qemuDomainObjBeginNestedJob, qemuDomainObjBeginJobInternal): Fix clients. * src/util/virlog.c (virLogFormatString): Likewise. * src/util/vireventpoll.c (virEventPollInterruptLocked): Likewise. Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
9eafa25116
commit
22d12905e6
@ -187,7 +187,7 @@ qemuDomainObjTransferJob(virDomainObjPtr obj)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||
|
||||
VIR_DEBUG("Changing job owner from %d to %d",
|
||||
VIR_DEBUG("Changing job owner from %llu to %llu",
|
||||
priv->job.owner, virThreadSelfID());
|
||||
priv->job.owner = virThreadSelfID();
|
||||
}
|
||||
@ -846,7 +846,7 @@ qemuDomainObjSetJobPhase(virQEMUDriverPtr driver,
|
||||
int phase)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||
int me = virThreadSelfID();
|
||||
unsigned long long me = virThreadSelfID();
|
||||
|
||||
if (!priv->job.asyncJob)
|
||||
return;
|
||||
@ -856,7 +856,7 @@ qemuDomainObjSetJobPhase(virQEMUDriverPtr driver,
|
||||
qemuDomainAsyncJobPhaseToString(priv->job.asyncJob, phase));
|
||||
|
||||
if (priv->job.asyncOwner && me != priv->job.asyncOwner) {
|
||||
VIR_WARN("'%s' async job is owned by thread %d",
|
||||
VIR_WARN("'%s' async job is owned by thread %llu",
|
||||
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
|
||||
priv->job.asyncOwner);
|
||||
}
|
||||
@ -898,7 +898,7 @@ qemuDomainObjReleaseAsyncJob(virDomainObjPtr obj)
|
||||
qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
|
||||
|
||||
if (priv->job.asyncOwner != virThreadSelfID()) {
|
||||
VIR_WARN("'%s' async job is owned by thread %d",
|
||||
VIR_WARN("'%s' async job is owned by thread %llu",
|
||||
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
|
||||
priv->job.asyncOwner);
|
||||
}
|
||||
@ -992,7 +992,7 @@ retry:
|
||||
|
||||
error:
|
||||
VIR_WARN("Cannot start job (%s, %s) for domain %s;"
|
||||
" current job is (%s, %s) owned by (%d, %d)",
|
||||
" current job is (%s, %s) owned by (%llu, %llu)",
|
||||
qemuDomainJobTypeToString(job),
|
||||
qemuDomainAsyncJobTypeToString(asyncJob),
|
||||
obj->def->name,
|
||||
@ -1056,7 +1056,7 @@ qemuDomainObjBeginNestedJob(virQEMUDriverPtr driver,
|
||||
}
|
||||
|
||||
if (priv->job.asyncOwner != virThreadSelfID()) {
|
||||
VIR_WARN("This thread doesn't seem to be the async job owner: %d",
|
||||
VIR_WARN("This thread doesn't seem to be the async job owner: %llu",
|
||||
priv->job.asyncOwner);
|
||||
}
|
||||
|
||||
|
@ -102,11 +102,11 @@ VIR_ENUM_DECL(qemuDomainAsyncJob)
|
||||
struct qemuDomainJobObj {
|
||||
virCond cond; /* Use to coordinate jobs */
|
||||
enum qemuDomainJob active; /* Currently running job */
|
||||
int owner; /* Thread which set current job */
|
||||
unsigned long long owner; /* Thread id which set current job */
|
||||
|
||||
virCond asyncCond; /* Use to coordinate with async jobs */
|
||||
enum qemuDomainAsyncJob asyncJob; /* Currently active async job */
|
||||
int asyncOwner; /* Thread which set current async job */
|
||||
unsigned long long asyncOwner; /* Thread which set current async job */
|
||||
int phase; /* Job phase (mainly for migrations) */
|
||||
unsigned long long mask; /* Jobs allowed during async job */
|
||||
unsigned long long start; /* When the async job started */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* vireventpoll.c: Poll based event loop for monitoring file handles
|
||||
*
|
||||
* Copyright (C) 2007, 2010-2012 Red Hat, Inc.
|
||||
* Copyright (C) 2007, 2010-2013 Red Hat, Inc.
|
||||
* Copyright (C) 2007 Daniel P. Berrange
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -708,7 +708,7 @@ static int virEventPollInterruptLocked(void)
|
||||
|
||||
if (!eventLoop.running ||
|
||||
virThreadIsSelf(&eventLoop.leader)) {
|
||||
VIR_DEBUG("Skip interrupt, %d %d", eventLoop.running,
|
||||
VIR_DEBUG("Skip interrupt, %d %llu", eventLoop.running,
|
||||
virThreadID(&eventLoop.leader));
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* virlog.c: internal logging and debugging
|
||||
*
|
||||
* Copyright (C) 2008, 2010-2012 Red Hat, Inc.
|
||||
* Copyright (C) 2008, 2010-2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -708,11 +708,11 @@ virLogFormatString(char **msg,
|
||||
* to just grep for it to find the right place.
|
||||
*/
|
||||
if ((funcname != NULL)) {
|
||||
ret = virAsprintf(msg, "%d: %s : %s:%d : %s\n",
|
||||
ret = virAsprintf(msg, "%llu: %s : %s:%d : %s\n",
|
||||
virThreadSelfID(), virLogPriorityString(priority),
|
||||
funcname, linenr, str);
|
||||
} else {
|
||||
ret = virAsprintf(msg, "%d: %s : %s\n",
|
||||
ret = virAsprintf(msg, "%llu: %s : %s\n",
|
||||
virThreadSelfID(), virLogPriorityString(priority),
|
||||
str);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* virthread.h: basic thread synchronization primitives
|
||||
*
|
||||
* Copyright (C) 2009-2011 Red Hat, Inc.
|
||||
* Copyright (C) 2009-2011, 2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -63,8 +63,8 @@ void virThreadCancel(virThreadPtr thread);
|
||||
* guaranteed to give unique values for distinct threads on all
|
||||
* architectures, nor are the two functions guaranteed to give the same
|
||||
* value for the same thread. */
|
||||
int virThreadSelfID(void);
|
||||
int virThreadID(virThreadPtr thread);
|
||||
unsigned long long virThreadSelfID(void);
|
||||
unsigned long long virThreadID(virThreadPtr thread);
|
||||
|
||||
/* Static initialization of mutexes is not possible, so we instead
|
||||
* provide for guaranteed one-time initialization via a callback
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* virthreadpthread.c: basic thread synchronization primitives
|
||||
*
|
||||
* Copyright (C) 2009-2011 Red Hat, Inc.
|
||||
* Copyright (C) 2009-2011, 2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -210,25 +210,35 @@ bool virThreadIsSelf(virThreadPtr thread)
|
||||
return pthread_equal(pthread_self(), thread->thread) ? true : false;
|
||||
}
|
||||
|
||||
/* For debugging use only; this result is not guaranteed unique on BSD
|
||||
* systems when pthread_t is a 64-bit pointer. */
|
||||
int virThreadSelfID(void)
|
||||
/* For debugging use only; this result is not guaranteed unique if
|
||||
* pthread_t is larger than a 64-bit pointer, nor does it always match
|
||||
* the pthread_self() id on Linux. */
|
||||
unsigned long long virThreadSelfID(void)
|
||||
{
|
||||
#if defined(HAVE_SYS_SYSCALL_H) && defined(SYS_gettid)
|
||||
pid_t tid;
|
||||
tid = syscall(SYS_gettid);
|
||||
return (int)tid;
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
return tid;
|
||||
#else
|
||||
return (int)(intptr_t)(void *)pthread_self();
|
||||
union {
|
||||
unsigned long long l;
|
||||
pthread_t t;
|
||||
} u;
|
||||
u.t = pthread_self();
|
||||
return u.l;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* For debugging use only; this result is not guaranteed unique on BSD
|
||||
* systems when pthread_t is a 64-bit pointer, nor does it match the
|
||||
* thread id of virThreadSelfID on Linux. */
|
||||
int virThreadID(virThreadPtr thread)
|
||||
/* For debugging use only; this result is not guaranteed unique if
|
||||
* pthread_t is larger than a 64-bit pointer, nor does it always match
|
||||
* the thread id of virThreadSelfID on Linux. */
|
||||
unsigned long long virThreadID(virThreadPtr thread)
|
||||
{
|
||||
return (int)(uintptr_t)thread->thread;
|
||||
union {
|
||||
unsigned long long l;
|
||||
pthread_t t;
|
||||
} u;
|
||||
u.t = thread->thread;
|
||||
return u.l;
|
||||
}
|
||||
|
||||
void virThreadJoin(virThreadPtr thread)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* virthreadwin32.c: basic thread synchronization primitives
|
||||
*
|
||||
* Copyright (C) 2009-2011 Red Hat, Inc.
|
||||
* Copyright (C) 2009-2011, 2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -334,14 +334,14 @@ bool virThreadIsSelf(virThreadPtr thread)
|
||||
return self.thread == thread->thread ? true : false;
|
||||
}
|
||||
|
||||
/* For debugging use only; see comments in threads-pthread.c. */
|
||||
int virThreadSelfID(void)
|
||||
/* For debugging use only; see comments in virthreadpthread.c. */
|
||||
unsigned long long virThreadSelfID(void)
|
||||
{
|
||||
return (int)GetCurrentThreadId();
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
/* For debugging use only; see comments in threads-pthread.c. */
|
||||
int virThreadID(virThreadPtr thread)
|
||||
/* For debugging use only; see comments in virthreadpthread.c. */
|
||||
unsigned long long virThreadID(virThreadPtr thread)
|
||||
{
|
||||
return (intptr_t)thread->thread;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user