summaryrefslogtreecommitdiff
path: root/src/atimer.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2014-03-25 07:43:26 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2014-03-25 07:43:26 -0700
commit1e952f0a7a1d0cc533438dcad37db08d8af6855f (patch)
tree423d42b20476efd08fa7c0e4b62756c1b09c8cdd /src/atimer.c
parent1edb4a2ec657c305880901e78317daf1990b5358 (diff)
downloademacs-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.c38
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);
}
}