* bug#15561: periodic timer stops running
2014-02-27 15:17 periodic timer stops running Peter Münster
@ 2014-02-27 20:43 ` Paul Eggert
0 siblings, 0 replies; 2+ messages in thread
From: Paul Eggert @ 2014-02-27 20:43 UTC (permalink / raw)
To: Peter Münster, 15561
[-- Attachment #1: Type: text/plain, Size: 174 bytes --]
Following up to:
http://lists.gnu.org/archive/html/emacs-devel/2014-02/msg00593.html
Does the attached patch fix things for you? It's relative to Emacs
trunk bzr 116586.
[-- Attachment #2: timer.diff --]
[-- Type: text/x-patch, Size: 11946 bytes --]
=== modified file 'src/atimer.c'
--- src/atimer.c 2014-01-01 07:43:34 +0000
+++ src/atimer.c 2014-02-27 20:15:21 +0000
@@ -50,22 +50,17 @@
/* 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);
-}
-static void
-block_atimers (void)
-{
- sigmask_atimers (SIG_BLOCK);
-}
-static void
-unblock_atimers (void)
-{
- sigmask_atimers (SIG_UNBLOCK);
+ pthread_sigmask (SIG_BLOCK, &blocked, oldset);
+}
+static void
+unblock_atimers (sigset_t const *oldset)
+{
+ pthread_sigmask (SIG_SETMASK, oldset, 0);
}
/* Function prototypes. */
@@ -98,6 +93,7 @@
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 @@
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 @@
/* 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 @@
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 @@
}
}
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
@@ -217,7 +214,8 @@
void
stop_other_atimers (struct atimer *t)
{
- block_atimers ();
+ sigset_t oldset;
+ block_atimers (&oldset);
if (t)
{
@@ -242,7 +240,7 @@
stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
atimers = t;
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
@@ -256,8 +254,9 @@
{
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 @@
t = next;
}
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
}
@@ -381,9 +380,10 @@
{
if (atimers)
{
- block_atimers ();
+ sigset_t oldset;
+ block_atimers (&oldset);
run_timers ();
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
}
=== modified file 'src/callproc.c'
--- src/callproc.c 2014-01-30 17:22:30 +0000
+++ src/callproc.c 2014-02-27 20:18:18 +0000
@@ -108,20 +108,20 @@
/* Block SIGCHLD. */
void
-block_child_signal (void)
+block_child_signal (sigset_t *oldset)
{
sigset_t blocked;
sigemptyset (&blocked);
sigaddset (&blocked, SIGCHLD);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ pthread_sigmask (SIG_BLOCK, &blocked, oldset);
}
/* Unblock SIGCHLD. */
void
-unblock_child_signal (void)
+unblock_child_signal (sigset_t const *oldset)
{
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ pthread_sigmask (SIG_SETMASK, oldset, 0);
}
/* Return the current buffer's working directory, or the home
@@ -162,7 +162,8 @@
void
record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile)
{
- block_child_signal ();
+ sigset_t oldset;
+ block_child_signal (&oldset);
if (p->alive)
{
@@ -171,7 +172,7 @@
kill (- p->pid, SIGKILL);
}
- unblock_child_signal ();
+ unblock_child_signal (&oldset);
}
/* Clean up files, file descriptors and processes created by Fcall_process. */
@@ -313,6 +314,7 @@
char *tempfile = NULL;
int pid;
#else
+ sigset_t oldset;
pid_t pid;
#endif
int child_errno;
@@ -629,7 +631,7 @@
#ifndef MSDOS
block_input ();
- block_child_signal ();
+ block_child_signal (&oldset);
#ifdef WINDOWSNT
pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir);
@@ -671,7 +673,7 @@
if (pid == 0)
{
- unblock_child_signal ();
+ unblock_child_signal (&oldset);
setsid ();
@@ -707,7 +709,7 @@
}
}
- unblock_child_signal ();
+ unblock_child_signal (&oldset);
unblock_input ();
#endif /* not MSDOS */
=== modified file 'src/keyboard.c'
--- src/keyboard.c 2014-02-24 14:26:49 +0000
+++ src/keyboard.c 2014-02-27 20:23:38 +0000
@@ -10295,6 +10295,9 @@
handle_interrupt (bool in_signal_handler)
{
char c;
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGINT);
cancel_echoing ();
@@ -10306,9 +10309,6 @@
/* If SIGINT isn't blocked, don't let us be interrupted by
a SIGINT. It might be harmful due to non-reentrancy
in I/O functions. */
- sigset_t blocked;
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGINT);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
}
@@ -10393,7 +10393,7 @@
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
immediate_quit = 0;
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
saved = gl_state;
GCPRO4 (saved.object, saved.global_code,
saved.current_syntax_table, saved.old_prop);
@@ -10414,7 +10414,7 @@
}
}
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
/* TODO: The longjmp in this call throws the NS event loop integration off,
and it seems to do fine without this. Probably some attention
=== modified file 'src/lisp.h'
--- src/lisp.h 2014-01-03 06:47:27 +0000
+++ src/lisp.h 2014-02-27 20:32:01 +0000
@@ -4237,8 +4237,8 @@
extern void sys_subshell (void);
extern void sys_suspend (void);
extern void discard_tty_input (void);
-extern void block_tty_out_signal (void);
-extern void unblock_tty_out_signal (void);
+extern void block_tty_out_signal (sigset_t *);
+extern void unblock_tty_out_signal (sigset_t const *);
extern void init_sys_modes (struct tty_display_info *);
extern void reset_sys_modes (struct tty_display_info *);
extern void init_all_sys_modes (void);
=== modified file 'src/process.c'
--- src/process.c 2014-02-22 21:08:22 +0000
+++ src/process.c 2014-02-27 20:19:36 +0000
@@ -1660,6 +1660,7 @@
bool pty_flag = 0;
char pty_name[PTY_NAME_SIZE];
Lisp_Object lisp_pty_name = Qnil;
+ sigset_t oldset;
inchannel = outchannel = -1;
@@ -1725,7 +1726,7 @@
setup_process_coding_systems (process);
block_input ();
- block_child_signal ();
+ block_child_signal (&oldset);
#ifndef WINDOWSNT
/* vfork, and prevent local vars from being clobbered by the vfork. */
@@ -1849,7 +1850,7 @@
signal (SIGPIPE, SIG_DFL);
/* Stop blocking SIGCHLD in the child. */
- unblock_child_signal ();
+ unblock_child_signal (&oldset);
if (pty_flag)
child_setup_tty (xforkout);
@@ -1868,7 +1869,7 @@
p->alive = 1;
/* Stop blocking in the parent. */
- unblock_child_signal ();
+ unblock_child_signal (&oldset);
unblock_input ();
if (pid < 0)
@@ -7055,8 +7056,9 @@
catch_child_signal (void)
{
struct sigaction action, old_action;
+ sigset_t oldset;
emacs_sigaction_init (&action, deliver_child_signal);
- block_child_signal ();
+ block_child_signal (&oldset);
sigaction (SIGCHLD, &action, &old_action);
eassert (! (old_action.sa_flags & SA_SIGINFO));
@@ -7065,7 +7067,7 @@
= (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN
? dummy_handler
: old_action.sa_handler);
- unblock_child_signal ();
+ unblock_child_signal (&oldset);
}
\f
=== modified file 'src/process.h'
--- src/process.h 2014-01-01 07:43:34 +0000
+++ src/process.h 2014-02-27 20:19:31 +0000
@@ -213,8 +213,8 @@
/* Defined in callproc.c. */
-extern void block_child_signal (void);
-extern void unblock_child_signal (void);
+extern void block_child_signal (sigset_t *);
+extern void unblock_child_signal (sigset_t const *);
extern Lisp_Object encode_current_directory (void);
extern void record_kill_process (struct Lisp_Process *, Lisp_Object);
=== modified file 'src/sound.c'
--- src/sound.c 2014-01-01 07:43:34 +0000
+++ src/sound.c 2014-02-27 20:31:39 +0000
@@ -702,7 +702,7 @@
{
int val;
#ifdef USABLE_SIGIO
- sigset_t blocked;
+ sigset_t oldset, blocked;
#endif
eassert (sd->fd >= 0);
@@ -714,7 +714,7 @@
#ifdef USABLE_SIGIO
sigemptyset (&blocked);
sigaddset (&blocked, SIGIO);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
#endif
val = sd->format;
@@ -748,7 +748,7 @@
turn_on_atimers (1);
#ifdef USABLE_SIGIO
- pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
+ pthread_sigmask (SIG_SETMASK, &oldset, 0);
#endif
}
@@ -764,10 +764,10 @@
be interrupted by a signal. Block the ones we know to cause
troubles. */
#ifdef USABLE_SIGIO
- sigset_t blocked;
+ sigset_t blocked, oldset;
sigemptyset (&blocked);
sigaddset (&blocked, SIGIO);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
#endif
turn_on_atimers (0);
@@ -776,7 +776,7 @@
turn_on_atimers (1);
#ifdef USABLE_SIGIO
- pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
+ pthread_sigmask (SIG_SETMASK, &oldset, 0);
#endif
/* Close the device. */
=== modified file 'src/sysdep.c'
--- src/sysdep.c 2014-01-01 07:43:34 +0000
+++ src/sysdep.c 2014-02-27 20:33:23 +0000
@@ -692,21 +692,21 @@
/* Block and unblock SIGTTOU. */
void
-block_tty_out_signal (void)
+block_tty_out_signal (sigset_t *oldset)
{
#ifdef SIGTTOU
sigset_t blocked;
sigemptyset (&blocked);
sigaddset (&blocked, SIGTTOU);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ pthread_sigmask (SIG_BLOCK, &blocked, oldset);
#endif
}
void
-unblock_tty_out_signal (void)
+unblock_tty_out_signal (sigset_t const *oldset)
{
#ifdef SIGTTOU
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ pthread_sigmask (SIG_SETMASK, oldset, 0);
#endif
}
@@ -721,10 +721,11 @@
tcsetpgrp_without_stopping (int fd, pid_t pgid)
{
#ifdef SIGTTOU
+ sigset_t oldset;
block_input ();
- block_tty_out_signal ();
+ block_tty_out_signal (&oldset);
tcsetpgrp (fd, pgid);
- unblock_tty_out_signal ();
+ unblock_tty_out_signal (&oldset);
unblock_input ();
#endif
}
@@ -1525,9 +1526,6 @@
#endif
}
- if (! IEEE_FLOATING_POINT)
- sigaddset (&action->sa_mask, SIGFPE);
-
action->sa_handler = handler;
action->sa_flags = emacs_sigaction_flags ();
}
@@ -1643,7 +1641,10 @@
static _Noreturn void
handle_arith_signal (int sig)
{
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, sig);
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
xsignal0 (Qarith_error);
}
=== modified file 'src/term.c'
--- src/term.c 2014-01-25 08:25:51 +0000
+++ src/term.c 2014-02-27 20:33:17 +0000
@@ -3952,9 +3952,10 @@
/* setsid failed, presumably because Emacs is already a process
group leader. Fall back on the obsolescent way to dissociate
a controlling tty. */
- block_tty_out_signal ();
+ sigset_t oldset;
+ block_tty_out_signal (&oldset);
ioctl (fd, TIOCNOTTY, 0);
- unblock_tty_out_signal ();
+ unblock_tty_out_signal (&oldset);
#endif
}
}
@@ -3978,6 +3979,7 @@
int status;
struct tty_display_info *tty = NULL;
struct terminal *terminal = NULL;
+ sigset_t oldset;
bool ctty = false; /* True if asked to open controlling tty. */
if (!terminal_type)
@@ -4064,11 +4066,11 @@
/* On some systems, tgetent tries to access the controlling
terminal. */
- block_tty_out_signal ();
+ block_tty_out_signal (&oldset);
status = tgetent (tty->termcap_term_buffer, terminal_type);
if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1])
emacs_abort ();
- unblock_tty_out_signal ();
+ unblock_tty_out_signal (&oldset);
if (status < 0)
{
^ permalink raw reply [flat|nested] 2+ messages in thread