]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
build: avoid non-portable cast of pthread_t
authorEric Blake <eblake@redhat.com>
Thu, 2 May 2013 20:23:02 +0000 (14:23 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 3 May 2013 12:30:22 +0000 (06:30 -0600)
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>
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/util/vireventpoll.c
src/util/virlog.c
src/util/virthread.h
src/util/virthreadpthread.c
src/util/virthreadwin32.c

index 47edfba9e54a722e6ded808fc8fcc8929e189e2b..33088ea572b12da6cfbaad23a273c83db74faf60 100644 (file)
@@ -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);
     }
 
index da04377b110ed1b5eca0ea02967b4fe4e31b4e9d..042e57d9a63f4c03f3a41f501556023596a614f2 100644 (file)
@@ -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 */
index 5c6d31bc4e3216f2d1bb9239f8aa6f1044c07231..1f0e5b61cae87919909034b5ab7e8a00a3d08b21 100644 (file)
@@ -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;
     }
index bd47b38e2c11fb97da55a5ee4c184e9e2b11d31d..eee9ddce74632ba236b7e9ca26bf7f249893cdb2 100644 (file)
@@ -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);
     }
index ca1306a8ab9aaca02fc53de63770d445b2a85ebf..84d3bdc8287b48f7b5587f3a5fc9860c3ac8e35f 100644 (file)
@@ -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
index b42b333853daca8e1a063da10f872b1477f770ed..75b5fd6fb6cd928d4e31a2160f51a3db75556355 100644 (file)
@@ -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)
index 4543ad864ee6d915b6980e8285ab4d506c1d49cd..bbe090f4c07ae5f04a419bebf2010c347a47c590 100644 (file)
@@ -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;
 }