[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#433031: qt4-x11: broken threading on alpha, hangs uselessly on startup



Package: qt4-x11
Version: 4.3.0-2
Severity: serious

qt4-x11 is completely broken on alpha right now; any qt4 apps hang
indefinitely on startup.  This can be seen in any recent build logs for
qt4-using packages.

- QMutex::lock() is called, which in turn calls
  QBasicAtomic::fetchAndAddAcquire(1).
- fetchAndAddAcquire() wraps an architecture-specific
  q_atomic_fetch_and_add_acquire_int() call.
- the alpha implementation of this call is broken: it returns 1 on success
  because the retval is (old != -1), which should always be true.
- as a result, fetchAndAddAcquire() returns true on alpha, but
  QMutex::lock() expects a successful call to return 0 rather than 1 and
  treats this as a failure.
- QMutex::lock() falls through to a pthread-based wait for the lock
  (pthread_cond_wait()), which never returns because there are no other
  threads anywhere to signal the current thread.

I believe that the attached patch fixes this problem; however, I am
including debian-alpha on X-Debbugs-Cc because I'm not confident I
understand the original reason for the (old != -1) check and would like some
additional eyeballs on it.  Applying this patch makes Qt apps work again for
me, but these are all simple single-thread applications, so getting the
locking semantics wrong would cause no problems here but would cause
significant (and hard-to-debug) problems later.

-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
vorlon@debian.org                                   http://www.debian.org/
diff -u qt4-x11-4.3.0/debian/changelog qt4-x11-4.3.0/debian/changelog
--- qt4-x11-4.3.0/debian/changelog
+++ qt4-x11-4.3.0/debian/changelog
@@ -1,3 +1,14 @@
+qt4-x11 (4.3.0-2.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix apparent cut-n-paste error in the newly added atomic APIs on alpha,
+    as the sign of the check seems to be the opposite of what it should be
+    and as a result all qt4 now hang indefinitely waiting for non-existent
+    other threads.
+  * Fix duplicate call to d->self().
+
+ -- Steve Langasek <vorlon@debian.org>  Fri, 13 Jul 2007 00:57:33 -0700
+
 qt4-x11 (4.3.0-2) unstable; urgency=low
 
   [Brian Nelson]
only in patch2:
unchanged:
--- qt4-x11-4.3.0.orig/src/corelib/arch/qatomic_alpha.h
+++ qt4-x11-4.3.0/src/corelib/arch/qatomic_alpha.h
@@ -208,7 +208,7 @@
                  : "=&r" (old), "=&r" (tmp), "+m"(*ptr)
                  : "r" (value)
                  : "memory");
-    return old != -1;
+    return old == -1;
 }
 
 inline int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value)
@@ -226,7 +226,7 @@
                  : "=&r" (old), "=&r" (tmp), "+m"(*ptr)
                  : "r" (value)
                  : "memory");
-    return old != -1;
+    return old == -1;
 }
 
 #else // !Q_CC_GNU
only in patch2:
unchanged:
--- qt4-x11-4.3.0.orig/src/corelib/thread/qmutex.cpp
+++ qt4-x11-4.3.0/src/corelib/thread/qmutex.cpp
@@ -175,9 +175,6 @@
 void QMutex::lock()
 {
     ulong self = 0;
-#ifndef QT_NO_DEBUG
-    self = d->self();
-#endif
     if (d->recursive) {
         self = d->self();
         if (d->owner == self) {
@@ -186,6 +183,10 @@
             return;
         }
     }
+#ifndef QT_NO_DEBUG
+    else
+        self = d->self();
+#endif
     
     bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
     if (!isLocked) {

Reply to: