summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-08-06 16:52:12 -0700
committerKeith Packard <keithp@keithp.com>2012-08-06 16:52:12 -0700
commit02f94b2d446f6700f791f318c551ac835af8445a (patch)
tree57e62fecf6051a02c0d404cbf534a80b94609b4c
parent360fa7736b214cae3ccd39feb4dc87b9e7e9734c (diff)
parent7f09126e068015db54c56bb982b8f91065375700 (diff)
Merge remote-tracking branch 'whot/for-keith'
-rw-r--r--dix/getevents.c2
-rw-r--r--os/utils.c13
-rw-r--r--test/os.c36
3 files changed, 43 insertions, 8 deletions
diff --git a/dix/getevents.c b/dix/getevents.c
index 27c2e04d1..b3bb162ae 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;
diff --git a/os/utils.c b/os/utils.c
index cdf5fd82e..947f8673a 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 1460a34d6..8f1107ded 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;
}