xserver: Branch 'master' - 3 commits

Keith Packard keithp at kemper.freedesktop.org
Mon Aug 6 16:52:43 PDT 2012


 dix/getevents.c |    2 ++
 os/utils.c      |   13 +++++--------
 test/os.c       |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 8 deletions(-)

New commits:
commit 02f94b2d446f6700f791f318c551ac835af8445a
Merge: 360fa77... 7f09126...
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Aug 6 16:52:12 2012 -0700

    Merge remote-tracking branch 'whot/for-keith'

commit 7f09126e068015db54c56bb982b8f91065375700
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Aug 3 15:36:34 2012 +1000

    os: don't unconditionally unblock SIGIO in OsReleaseSignals()
    
    Calling OsReleaseSignal() inside the signal handler releases SIGIO, causing
    the signal handler to be called again from within the handler.
    
    Practical use-case: when synaptics calls TimerSet in the signal handler,
    this causes the signals to be released, eventually hanging the server.
    
    Regression introduced in 08962951de.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/os/utils.c b/os/utils.c
index cdf5fd8..947f867 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1186,6 +1186,7 @@ OsBlockSignals(void)
 
 #ifdef SIG_BLOCK
 static sig_atomic_t sigio_blocked;
+static sigset_t PreviousSigIOMask;
 #endif
 
 /**
@@ -1198,13 +1199,13 @@ OsBlockSIGIO(void)
 #ifdef SIGIO
 #ifdef SIG_BLOCK
     if (sigio_blocked++ == 0) {
-        sigset_t set, old;
+        sigset_t set;
         int ret;
 
         sigemptyset(&set);
         sigaddset(&set, SIGIO);
-        sigprocmask(SIG_BLOCK, &set, &old);
-        ret = sigismember(&old, SIGIO);
+        sigprocmask(SIG_BLOCK, &set, &PreviousSigIOMask);
+        ret = sigismember(&PreviousSigIOMask, SIGIO);
         return ret;
     } else
         return 1;
@@ -1218,11 +1219,7 @@ OsReleaseSIGIO(void)
 #ifdef SIGIO
 #ifdef SIG_BLOCK
     if (--sigio_blocked == 0) {
-        sigset_t set;
-
-        sigemptyset(&set);
-        sigaddset(&set, SIGIO);
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
+        sigprocmask(SIG_SETMASK, &PreviousSigIOMask, 0);
     } else if (sigio_blocked < 0) {
         BUG_WARN(sigio_blocked < 0);
         sigio_blocked = 0;
diff --git a/test/os.c b/test/os.c
index 1460a34..8f1107d 100644
--- a/test/os.c
+++ b/test/os.c
@@ -28,6 +28,21 @@
 #include <signal.h>
 #include "os.h"
 
+static int last_signal = 0;
+static int expect_signal = 0;
+
+static void sighandler(int signal)
+{
+    assert(expect_signal);
+    expect_signal = 0;
+    if (!last_signal)
+        raise(signal);
+    OsBlockSignals();
+    OsReleaseSignals();
+    last_signal = 1;
+    expect_signal = 1;
+}
+
 static int
 sig_is_blocked(int sig)
 {
@@ -118,7 +133,27 @@ static void block_sigio_test(void)
     assert(sig_is_blocked(SIGIO));
     OsReleaseSignals();
     assert(!sig_is_blocked(SIGIO));
+#endif
+}
 
+static void block_sigio_test_nested(void)
+{
+#ifdef SIG_BLOCK
+    /* Check for bug releasing SIGIO during SIGIO signal handling.
+       test case:
+           raise signal
+           → in signal handler:
+                raise signal
+                OsBlockSignals()
+                OsReleaseSignals()
+                tail guard
+       tail guard must be hit.
+     */
+    sighandler_t old_handler;
+    old_handler = signal(SIGIO, sighandler);
+    expect_signal = 1;
+    assert(raise(SIGIO) == 0);
+    assert(signal(SIGIO, old_handler) == sighandler);
 #endif
 }
 
@@ -126,5 +161,6 @@ int
 main(int argc, char **argv)
 {
     block_sigio_test();
+    block_sigio_test_nested();
     return 0;
 }
commit cb306a8f174bec9ded95191b91797f59250e6808
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jul 31 16:09:38 2012 +1000

    dix: make sure the mask is set for emulated scroll events (#52508)
    
    If a device has smooth scrolling axes, but submits scroll button events, we
    convert those to motion events and update the valuators. For legacy button
    events, the valuator mask is likely unset though, causing
    add_to_scroll_valuator() to return early, leaving us with an empty mask.
    That again skipped the rest of the code and no events were generated.
    
    Fix it by making sure that the scroll valuator in the mask is at least
    initialized to 0.
    
    Broke evdev wheel emulation, introduced by
    54476b5e4461ff523e935961affabcf0de12c556.
    
    X.Org Bug 52508 <http://bugs.freedesktop.org/show_bug.cgi?id=52508>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index 27c2e04..b3bb162 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1625,6 +1625,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
 
         if (adj != 0.0 && axis != -1) {
             adj *= pDev->valuator->axes[axis].scroll.increment;
+            if (!valuator_mask_isset(&mask, axis))
+                valuator_mask_set(&mask, axis, 0);
             add_to_scroll_valuator(pDev, &mask, axis, adj);
             type = MotionNotify;
             buttons = 0;


More information about the xorg-commit mailing list