all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#15561: periodic timer stops running
  2014-02-27 15:17 Peter Münster
@ 2014-02-27 20:43 ` Paul Eggert
  0 siblings, 0 replies; 17+ 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] 17+ messages in thread

* bug#15561: Fwd: bug#15561: periodic timer stops running
       [not found] <CAFM41H34WhVZ_fCWoh9BxDqs07OPXi_u=5ghTHkv_zAp22SxBA@mail.gmail.com>
@ 2014-02-27 22:11 ` Barry OReilly
       [not found] ` <530FF70C.2020905@cs.ucla.edu>
  1 sibling, 0 replies; 17+ messages in thread
From: Barry OReilly @ 2014-02-27 22:11 UTC (permalink / raw
  To: 15561

[-- Attachment #1: Type: text/plain, Size: 455 bytes --]

The patch addresses:

> If it means to block SIGALRM during timers, that doesn't always
> happen because timers run within timers. The end of an inner timer
> would unblock SIGALRM and the outer timer would finish with the
> sigmask unblocked.

but I don't see it address:

> But what happens if the next timer happens to be soon, and Emacs
> receives SIGALRM inbetween set_alarm and unblock_timers?

That one sounds more likely to cause a timer to stop.

[-- Attachment #2: Type: text/html, Size: 613 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
       [not found] ` <530FF70C.2020905@cs.ucla.edu>
@ 2014-02-28  2:42   ` Paul Eggert
  2014-02-28  8:03     ` bug#15561: " Dmitry Antipov
  0 siblings, 1 reply; 17+ messages in thread
From: Paul Eggert @ 2014-02-28  2:42 UTC (permalink / raw
  To: Barry OReilly; +Cc: 15561

[Resending with corrected bug-report address; sorry about that.]

Barry OReilly wrote:
> But what happens if the next timer happens to be soon, and Emacs receives SIGALRM inbetween set_alarm and unblock_timers?

Are you talking about a SIGALRM received during the execution of 
do_pending_atimers, between run_timer's call to set_alarm and 
do_pending_atimers's call to unblock_atimers?  If so, the SIGALRM should 
be held by the operating system during that period, and Emacs won't be 
informed of the SIGALRM until unblock_atimers does its thing.  Sorry, I 
don't see how this would cause a timer to stop.





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: Re: bug#15561: periodic timer stops running
  2014-02-28  2:42   ` Paul Eggert
@ 2014-02-28  8:03     ` Dmitry Antipov
  2014-02-28  9:18       ` Eli Zaretskii
  0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Antipov @ 2014-02-28  8:03 UTC (permalink / raw
  To: Paul Eggert; +Cc: 15561

On 02/28/2014 06:42 AM, Paul Eggert wrote:

> [Resending with corrected bug-report address; sorry about that.]
>
> Barry OReilly wrote:
>> But what happens if the next timer happens to be soon, and Emacs receives SIGALRM inbetween set_alarm and unblock_timers?
>
> Are you talking about a SIGALRM received during the execution of do_pending_atimers, between run_timer's call to set_alarm and do_pending_atimers's call to unblock_atimers?  If so, the SIGALRM should
> be held by the operating system during that period, and Emacs won't be informed of the SIGALRM until unblock_atimers does its thing.  Sorry, I don't see how this would cause a timer to stop.

BTW, we have at least one backtrace with nested calls to timer_check_2 (http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16817#11):

...
64  Emacs                               0x00000001002067b2 Ffuncall + 1762 (eval.c:2827)
65  Emacs                               0x00000001002070e9 call1 + 73 (eval.c:2572)
66  Emacs                               0x000000010013d6a6 timer_check_2 + 1846 (keyboard.c:4447)                   ;; Nested call
67  Emacs                               0x000000010013cef5 timer_check + 165 (keyboard.c:4514)
68  Emacs                               0x0000000100139c25 readable_events + 37 (keyboard.c:3405)
69  Emacs                               0x000000010013cdb6 get_input_pending + 54 (keyboard.c:6794)
70  Emacs                               0x0000000100142ce4 Finput_pending_p + 132 (keyboard.c:10449)
71  Emacs                               0x000000010020652d Ffuncall + 1117 (eval.c:2775)
72  Emacs                               0x000000010027173a exec_byte_code + 3866 (bytecode.c:900)
73  Emacs                               0x0000000100207b6e funcall_lambda + 1566 (eval.c:3010)
74  Emacs                               0x00000001002067b2 Ffuncall + 1762 (eval.c:2827)
75  Emacs                               0x000000010027173a exec_byte_code + 3866 (bytecode.c:900)
76  Emacs                               0x0000000100207b6e funcall_lambda + 1566 (eval.c:3010)
77  Emacs                               0x00000001002067b2 Ffuncall + 1762 (eval.c:2827)
78  Emacs                               0x0000000100205b33 Fapply + 243 (eval.c:2255)
79  Emacs                               0x0000000100206403 Ffuncall + 819 (eval.c:2759)
80  Emacs                               0x000000010027173a exec_byte_code + 3866 (bytecode.c:900)
81  Emacs                               0x000000010027080f Fbyte_code + 63 (bytecode.c:475)
82  Emacs                               0x0000000100200e79 eval_sub + 2073 (eval.c:2149)
83  Emacs                               0x0000000100203d84 internal_lisp_condition_case + 772 (eval.c:1243)
84  Emacs                               0x0000000100272957 exec_byte_code + 8503 (bytecode.c:1096)
85  Emacs                               0x0000000100207b6e funcall_lambda + 1566 (eval.c:3010)
86  Emacs                               0x00000001002067b2 Ffuncall + 1762 (eval.c:2827)
87  Emacs                               0x00000001002070e9 call1 + 73 (eval.c:2572)
88  Emacs                               0x000000010013d6a6 timer_check_2 + 1846 (keyboard.c:4447)                   ;; First call
89  Emacs                               0x000000010013cef5 timer_check + 165 (keyboard.c:4514)
90  Emacs                               0x0000000100139c25 readable_events + 37 (keyboard.c:3405)
91  Emacs                               0x000000010013cdb6 get_input_pending + 54 (keyboard.c:6794)
92  Emacs                               0x00000001001382e6 detect_input_pending_run_timers + 54 (keyboard.c:10391)
93  Emacs                               0x0000000100280963 wait_reading_process_output + 4227 (process.c:4762)
94  Emacs                               0x00000001000087fa sit_for + 634 (dispnew.c:5981)
...

(I just wonder whether this behaviour is acceptable).

Dmitry






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: Re: bug#15561: periodic timer stops running
  2014-02-28  8:03     ` bug#15561: " Dmitry Antipov
@ 2014-02-28  9:18       ` Eli Zaretskii
  2014-02-28 13:51         ` Stefan Monnier
  0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2014-02-28  9:18 UTC (permalink / raw
  To: Dmitry Antipov; +Cc: eggert, 15561

> Date: Fri, 28 Feb 2014 12:03:09 +0400
> From: Dmitry Antipov <antipov@dev.rtsoft.ru>
> Cc: 15561@debbugs.gnu.org
> 
> BTW, we have at least one backtrace with nested calls to timer_check_2 (http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16817#11):

Perhaps we should bind Vtimer_list to nil when we call Lisp in
timer_check_2.

But in general, timer_check_2 works on a copy of Vtimer_list, so
calling it recursively is not necessarily a problem, I think.  Do you
see any potential problems?





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: Re: bug#15561: periodic timer stops running
  2014-02-28  9:18       ` Eli Zaretskii
@ 2014-02-28 13:51         ` Stefan Monnier
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Monnier @ 2014-02-28 13:51 UTC (permalink / raw
  To: Eli Zaretskii; +Cc: eggert, Dmitry Antipov, 15561

>> BTW, we have at least one backtrace with nested calls to timer_check_2
>> (http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16817#11):

That can clearly happen if a timer does things like sit-for.

> Perhaps we should bind Vtimer_list to nil when we call Lisp in
> timer_check_2.

No, because a timer may also want to schedule a new timer or cancel an
old one.


        Stefan





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2013-10-08 14:20 bug#15561: Timer can miss its SIGALRM Barry OReilly
@ 2014-02-28 14:43 ` Barry OReilly
  2014-02-28 14:50   ` Barry OReilly
  2014-03-02 15:58   ` Peter Münster
  2014-03-04  9:11 ` Peter Münster
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 17+ messages in thread
From: Barry OReilly @ 2014-02-28 14:43 UTC (permalink / raw
  To: eggert, pmlists, 15561

[-- Attachment #1: Type: text/plain, Size: 951 bytes --]

> Are you talking about a SIGALRM received during the execution of
> do_pending_atimers, between run_timer's call to set_alarm and
> do_pending_atimers's call to unblock_atimers? If so, the SIGALRM
> should be held by the operating system during that period, and Emacs
> won't be informed of the SIGALRM until unblock_atimers does its
> thing. Sorry, I don't see how this would cause a timer to stop.

I see you're right, because SIGALRM isn't specified with SIG_IGN at
any point.

While verifying that, I found in sys_subshell:

  struct save_signal saved_handlers[5];
  [...]
#ifdef USABLE_SIGIO
  saved_handlers[3].code = SIGIO;
  saved_handlers[4].code = 0;
#else
  saved_handlers[3].code = 0;
#endif

Shouldn't the else case initialize saved_handlers[4]? On the off
chance it is garbage valued coincidentally as SIGALRM, the subsequent
SIG_IGN could drop a pending SIGALRM.

Peter, which OS do you run? What is USABLE_SIGIO in your src/config.h?

[-- Attachment #2: Type: text/html, Size: 1110 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-02-28 14:43 ` bug#15561: periodic timer stops running Barry OReilly
@ 2014-02-28 14:50   ` Barry OReilly
  2014-03-02 15:58   ` Peter Münster
  1 sibling, 0 replies; 17+ messages in thread
From: Barry OReilly @ 2014-02-28 14:50 UTC (permalink / raw
  To: Paul Eggert, 15561, pmlists

[-- Attachment #1: Type: text/plain, Size: 137 bytes --]

save_signal_handlers (struct save_signal *saved_handlers)
{
  while (saved_handlers->code)

Nevermind, it short circuits at the first 0.

[-- Attachment #2: Type: text/html, Size: 182 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-02-28 14:43 ` bug#15561: periodic timer stops running Barry OReilly
  2014-02-28 14:50   ` Barry OReilly
@ 2014-03-02 15:58   ` Peter Münster
  2014-03-04  4:17     ` Barry OReilly
  1 sibling, 1 reply; 17+ messages in thread
From: Peter Münster @ 2014-03-02 15:58 UTC (permalink / raw
  To: Barry OReilly; +Cc: eggert, 15561

On Fri, Feb 28 2014, Barry OReilly wrote:

> Peter, which OS do you run?

Hi,

GNU/Linux (openSUSE-12.3).


> What is USABLE_SIGIO in your src/config.h?

It's 1.


The patch did not help.


Very probably a timer stops running just after system wake-up (after
suspend to ram), because at that moment several timers are triggered at
the same time.

Thanks for your efforts,
-- 
           Peter





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-03-02 15:58   ` Peter Münster
@ 2014-03-04  4:17     ` Barry OReilly
  0 siblings, 0 replies; 17+ messages in thread
From: Barry OReilly @ 2014-03-04  4:17 UTC (permalink / raw
  To: Peter Münster; +Cc: Paul Eggert, 15561

[-- Attachment #1: Type: text/plain, Size: 733 bytes --]

> Very probably a timer stops running just after system wake-up (after
> suspend to ram), because at that moment several timers are triggered
> at the same time.

I tried testing several timers going off at once, but reproduced no
problem.

;;; -*- lexical-binding:t -*-
(require 'cl-lib)
(let ((noninteractive nil))
  (cl-dotimes (timer-id 8)
    (run-at-time '(0 0 0 0)
                 0.1
                 (lambda ()
                   (message "%s DEBUG: Timer ID=%s" (current-time)
timer-id)
                   (sit-for 0 t)))))

All 8 fire without stopping.

Is it always the same timer that stops running, or have you seen
different timers in Emacs stop?

Could you come up with a recipe that allows us to reproduce the bug?

[-- Attachment #2: Type: text/html, Size: 863 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2013-10-08 14:20 bug#15561: Timer can miss its SIGALRM Barry OReilly
  2014-02-28 14:43 ` bug#15561: periodic timer stops running Barry OReilly
@ 2014-03-04  9:11 ` Peter Münster
  2014-03-05 17:13   ` Peter Münster
  2014-03-12 21:52   ` Barry OReilly
  2014-03-25  8:59 ` Peter Münster
  2014-04-24  5:29 ` Peter Münster
  3 siblings, 2 replies; 17+ messages in thread
From: Peter Münster @ 2014-03-04  9:11 UTC (permalink / raw
  To: Barry OReilly; +Cc: Paul Eggert, 15561

On Tue, Mar 04 2014, Barry OReilly wrote:

> Is it always the same timer that stops running, or have you seen
> different timers in Emacs stop?

Hi Barry,

Different timers.


> Could you come up with a recipe that allows us to reproduce the bug?

I don't know. It would be difficult:
- in happens only once or twice per day
- the timers depend on my personal environment: checking email, news,
  Bitcoin value, the todo-list of my org-file and so on
- some timers depend on idle-time

Would it help, if I a add some code to the start and to the end of each
timer function, that prints interesting information to the *Messages*
buffer? And when it happens again, we would get some trace?

-- 
           Peter





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-03-04  9:11 ` Peter Münster
@ 2014-03-05 17:13   ` Peter Münster
  2014-03-12 21:52   ` Barry OReilly
  1 sibling, 0 replies; 17+ messages in thread
From: Peter Münster @ 2014-03-05 17:13 UTC (permalink / raw
  To: 15561; +Cc: Barry OReilly, Paul Eggert

Perhaps related:

The following function make some beeps for some seconds. It is called
from a timer. Sometimes, the `cancel-timer' does not work, and emacs
continues to beep.

--8<---------------cut here---------------start------------->8---
(defun org-notify-action-ding (plist)
  "Make noise."
  (let ((timer (run-with-timer 0 1 'ding)))
    (run-with-timer (or (plist-get plist :duration) 3) nil
                    'cancel-timer timer)))
--8<---------------cut here---------------end--------------->8---

Or is this another problem/bug?

TIA for any help,
-- 
           Peter





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-03-04  9:11 ` Peter Münster
  2014-03-05 17:13   ` Peter Münster
@ 2014-03-12 21:52   ` Barry OReilly
  1 sibling, 0 replies; 17+ messages in thread
From: Barry OReilly @ 2014-03-12 21:52 UTC (permalink / raw
  To: Peter Münster; +Cc: 15561

[-- Attachment #1: Type: text/plain, Size: 925 bytes --]

> I don't know. It would be difficult:
> - in happens only once or twice per day
> - the timers depend on my personal environment: checking email,
>   news, Bitcoin value, the todo-list of my org-file and so on
> - some timers depend on idle-time

> Would it help, if I a add some code to the start and to the end of
> each timer function, that prints interesting information to the
> *Messages* buffer? And when it happens again, we would get some
> trace?

After the timers stop, do they start up again when you 'kill -s ALRM'
the Emacs process?

Maybe you could put a print statement in the handle_alarm_signal
function to confirm you get the signal. If you do, then perhaps start
debugging at the do_pending_atimers function.

If the problem is that you're not getting the signal, write a small
program that implements a simple timer using SIGALRM, run it
continuously, and see if it stops too under the same conditions.

[-- Attachment #2: Type: text/html, Size: 1066 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2013-10-08 14:20 bug#15561: Timer can miss its SIGALRM Barry OReilly
  2014-02-28 14:43 ` bug#15561: periodic timer stops running Barry OReilly
  2014-03-04  9:11 ` Peter Münster
@ 2014-03-25  8:59 ` Peter Münster
  2014-03-25 13:18   ` Barry OReilly
  2014-04-24  5:29 ` Peter Münster
  3 siblings, 1 reply; 17+ messages in thread
From: Peter Münster @ 2014-03-25  8:59 UTC (permalink / raw
  To: Barry OReilly; +Cc: 15561

On Wed, Mar 12 2014, Barry OReilly wrote:

> After the timers stop, do they start up again when you 'kill -s ALRM'
> the Emacs process?

The timers don't stop anymore since my distribution upgrade from
opensuse-12.3 to 13.1. Very odd...

I don't understand why, but the problem seems to be solved.

-- 
           Peter





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-03-25  8:59 ` Peter Münster
@ 2014-03-25 13:18   ` Barry OReilly
  2014-03-25 14:45     ` Paul Eggert
  0 siblings, 1 reply; 17+ messages in thread
From: Barry OReilly @ 2014-03-25 13:18 UTC (permalink / raw
  To: Peter Münster, Paul Eggert; +Cc: 15561

[-- Attachment #1: Type: text/plain, Size: 177 bytes --]

I think applying Paul Eggert's patch is all that's left to this bug
report then. Since it solves a theoretical flaw rather than one
witnessed, maybe it's appropriate for trunk?

[-- Attachment #2: Type: text/html, Size: 224 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2014-03-25 13:18   ` Barry OReilly
@ 2014-03-25 14:45     ` Paul Eggert
  0 siblings, 0 replies; 17+ messages in thread
From: Paul Eggert @ 2014-03-25 14:45 UTC (permalink / raw
  To: Barry OReilly, Peter Münster; +Cc: 15561-done

Barry OReilly wrote:
> I think applying Paul Eggert's patch is all that's left to this bug
> report then. Since it solves a theoretical flaw rather than one
> witnessed, maybe it's appropriate for trunk?

Sounds good; done as trunk bzr 116018.





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15561: periodic timer stops running
  2013-10-08 14:20 bug#15561: Timer can miss its SIGALRM Barry OReilly
                   ` (2 preceding siblings ...)
  2014-03-25  8:59 ` Peter Münster
@ 2014-04-24  5:29 ` Peter Münster
  3 siblings, 0 replies; 17+ messages in thread
From: Peter Münster @ 2014-04-24  5:29 UTC (permalink / raw
  To: Barry OReilly; +Cc: 15561

Hi,

It happened again: 2 periodic timers have stopped running.


On Wed, Mar 12 2014, Barry OReilly wrote:

> After the timers stop, do they start up again when you 'kill -s ALRM'
> the Emacs process?

No.


> Maybe you could put a print statement in the handle_alarm_signal
> function to confirm you get the signal.

Emacs goes into the handle_alarm_signal function when sending the
signal.


> If you do, then perhaps start debugging at the do_pending_atimers
> function.

I've tried, but I don't really know, where to look...

Here the value of my timer-list:

--8<---------------cut here---------------start------------->8---
Value: ([t 21335 18354 590042 20 org-notify-process nil nil 953248]
 [t 21335 20714 647433 9000 gnus-demon-run-callback
    (pm/rescan-news 900 9000)
    nil 138000]
 [nil 21336 7511 917609 300 savehist-autosave nil nil 848940]
 [nil 21336 7547 595349 300 gnus-demon-run-callback
      (gnus-group-save-newsrc 120 300)
      nil 925000]
 [nil 21336 7547 880984 60 pm/newmail-update nil nil 696000]
 [nil 21336 7641 823147 900 gnus-demon-run-callback
      (pm/btc-checker 60 900)
      nil 609000]
 [nil 21336 7727 644172 420 gnus-demon-run-callback
      (gnus-delay-send-queue 180 420)
      nil 412000]
 [nil 21336 7947 507382 3600 url-cookie-write-file nil nil 982000]
 [nil 21336 10875 981456 nil password-cache-remove
      ("auth-source-magic (:max 1 :host (\"news.gmane.org\" \"news.gmane.org\") :port (\"119\" \"nntp\" \"nntp\" \"563\" \"nntps\" \"snews\"))")
      nil 731000]
 [nil 21336 13307 647529 6000 gnus-demon-run-callback
      (pm/check-mail 180 6000)
      nil 832000])
--8<---------------cut here---------------end--------------->8---

What does the first entry in the vector mean (t or nil)? The 2 first
entries have stopped.

What could I do to debug this?

TIA for any hints,
-- 
           Peter





^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-04-24  5:29 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <CAFM41H34WhVZ_fCWoh9BxDqs07OPXi_u=5ghTHkv_zAp22SxBA@mail.gmail.com>
2014-02-27 22:11 ` bug#15561: Fwd: bug#15561: periodic timer stops running Barry OReilly
     [not found] ` <530FF70C.2020905@cs.ucla.edu>
2014-02-28  2:42   ` Paul Eggert
2014-02-28  8:03     ` bug#15561: " Dmitry Antipov
2014-02-28  9:18       ` Eli Zaretskii
2014-02-28 13:51         ` Stefan Monnier
2014-02-27 15:17 Peter Münster
2014-02-27 20:43 ` bug#15561: " Paul Eggert
  -- strict thread matches above, loose matches on Subject: below --
2013-10-08 14:20 bug#15561: Timer can miss its SIGALRM Barry OReilly
2014-02-28 14:43 ` bug#15561: periodic timer stops running Barry OReilly
2014-02-28 14:50   ` Barry OReilly
2014-03-02 15:58   ` Peter Münster
2014-03-04  4:17     ` Barry OReilly
2014-03-04  9:11 ` Peter Münster
2014-03-05 17:13   ` Peter Münster
2014-03-12 21:52   ` Barry OReilly
2014-03-25  8:59 ` Peter Münster
2014-03-25 13:18   ` Barry OReilly
2014-03-25 14:45     ` Paul Eggert
2014-04-24  5:29 ` Peter Münster

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.