diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2014-03-25 07:43:26 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2014-03-25 07:43:26 -0700 |
commit | 1e952f0a7a1d0cc533438dcad37db08d8af6855f (patch) | |
tree | 423d42b20476efd08fa7c0e4b62756c1b09c8cdd /src/atimer.c | |
parent | 1edb4a2ec657c305880901e78317daf1990b5358 (diff) | |
download | emacs-1e952f0a7a1d0cc533438dcad37db08d8af6855f.tar.gz emacs-1e952f0a7a1d0cc533438dcad37db08d8af6855f.tar.bz2 emacs-1e952f0a7a1d0cc533438dcad37db08d8af6855f.zip |
Handle sigmask better with nested signal handlers.
* atimer.c (sigmask_atimers): Remove.
Remaining use rewritten to use body of this function.
* atimer.c (block_atimers, unblock_atimers):
* callproc.c (block_child_signal, unblock_child_signal):
* sysdep.c (block_tty_out_signal, unblock_tty_out_signal):
New arg OLDSET. All callers changed.
* atimer.c (block_atimers, unblock_atimers):
* callproc.c (block_child_signal, unblock_child_signal):
* keyboard.c (handle_interrupt):
* sound.c (vox_configure, vox_close):
Restore the old signal mask rather than unilaterally clearing bits
from the mask, in case a handler is running within another
handler. All callers changed.
* lisp.h, process.c, process.h, term.c:
Adjust decls and callers to match new API.
* sysdep.c (emacs_sigaction_init): Don't worry about masking SIGFPE;
signal handlers aren't supposed to use floating point anyway.
(handle_arith_signal): Unblock just SIGFPE rather than clearing mask.
Fixes: debbugs:15561
Diffstat (limited to 'src/atimer.c')
-rw-r--r-- | src/atimer.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/src/atimer.c b/src/atimer.c index d98ddac0171..a5a2b0714e3 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -50,22 +50,17 @@ static bool alarm_timer_ok; /* Block/unblock SIGALRM. */ static void -sigmask_atimers (int how) +block_atimers (sigset_t *oldset) { sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGALRM); - pthread_sigmask (how, &blocked, 0); + pthread_sigmask (SIG_BLOCK, &blocked, oldset); } static void -block_atimers (void) +unblock_atimers (sigset_t const *oldset) { - sigmask_atimers (SIG_BLOCK); -} -static void -unblock_atimers (void) -{ - sigmask_atimers (SIG_UNBLOCK); + pthread_sigmask (SIG_SETMASK, oldset, 0); } /* Function prototypes. */ @@ -98,6 +93,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, atimer_callback fn, void *client_data) { struct atimer *t; + sigset_t oldset; /* Round TIME up to the next full second if we don't have itimers. */ @@ -122,7 +118,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, t->fn = fn; t->client_data = client_data; - block_atimers (); + block_atimers (&oldset); /* Compute the timer's expiration time. */ switch (type) @@ -143,7 +139,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, /* Insert the timer in the list of active atimers. */ schedule_atimer (t); - unblock_atimers (); + unblock_atimers (&oldset); /* Arrange for a SIGALRM at the time the next atimer is ripe. */ set_alarm (); @@ -158,8 +154,9 @@ void cancel_atimer (struct atimer *timer) { int i; + sigset_t oldset; - block_atimers (); + block_atimers (&oldset); for (i = 0; i < 2; ++i) { @@ -186,7 +183,7 @@ cancel_atimer (struct atimer *timer) } } - unblock_atimers (); + unblock_atimers (&oldset); } @@ -217,7 +214,8 @@ append_atimer_lists (struct atimer *list_1, struct atimer *list_2) void stop_other_atimers (struct atimer *t) { - block_atimers (); + sigset_t oldset; + block_atimers (&oldset); if (t) { @@ -242,7 +240,7 @@ stop_other_atimers (struct atimer *t) stopped_atimers = append_atimer_lists (atimers, stopped_atimers); atimers = t; - unblock_atimers (); + unblock_atimers (&oldset); } @@ -256,8 +254,9 @@ run_all_atimers (void) { struct atimer *t = atimers; struct atimer *next; + sigset_t oldset; - block_atimers (); + block_atimers (&oldset); atimers = stopped_atimers; stopped_atimers = NULL; @@ -268,7 +267,7 @@ run_all_atimers (void) t = next; } - unblock_atimers (); + unblock_atimers (&oldset); } } @@ -381,9 +380,10 @@ do_pending_atimers (void) { if (atimers) { - block_atimers (); + sigset_t oldset; + block_atimers (&oldset); run_timers (); - unblock_atimers (); + unblock_atimers (&oldset); } } |