summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2012-08-03 15:36:34 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2012-08-07 09:39:56 +1000
commit7f09126e068015db54c56bb982b8f91065375700 (patch)
treec933156e2632b185211e2de5109d92dbcc1b576b /os
parentcb306a8f174bec9ded95191b91797f59250e6808 (diff)
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@who-t.net> Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
Diffstat (limited to 'os')
-rw-r--r--os/utils.c13
1 files changed, 5 insertions, 8 deletions
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;