aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Colascione2025-06-10 11:39:19 -0700
committerDaniel Colascione2025-06-10 11:45:58 -0700
commit57b5be4eb9afe819bf67c73afc4d330dd3aacac2 (patch)
treeee3ecda6fc650d170422899184e790b90750c3b1
parentda92ad2eaa151b2f5865e6d9bc95fa7009860bd8 (diff)
downloademacs-dancol/quit-improvements.tar.gz
emacs-dancol/quit-improvements.zip
Improve timer robustness by protecting pending function callsdancol/quit-improvements
* src/keyboard.c (timer_check_2): Protect pending function calls with inhibit-quit and deactivate-mark bindings, same as timer callbacks. Also use specbind for deactivate-mark in timer handler for consistency.
-rw-r--r--src/keyboard.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 7b4929766bf..6b567390a95 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4708,11 +4708,22 @@ static struct timespec
4708timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) 4708timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4709{ 4709{
4710 /* First run the code that was delayed. */ 4710 /* First run the code that was delayed. */
4711 while (CONSP (pending_funcalls)) 4711 if (CONSP (pending_funcalls))
4712 { 4712 {
4713 Lisp_Object funcall = XCAR (pending_funcalls); 4713 /* safe_calln eats signals but doesn't block quit per se. Do it
4714 pending_funcalls = XCDR (pending_funcalls); 4714 here so C-g doesn't end execution of pending function calls
4715 safe_calln (Qapply, XCAR (funcall), XCDR (funcall)); 4715 prematurely. */
4716 specpdl_ref count = SPECPDL_INDEX ();
4717 specbind (Qinhibit_quit, Qt);
4718 specbind (Qdeactivate_mark, Vdeactivate_mark);
4719 while (CONSP (pending_funcalls))
4720 {
4721 Lisp_Object funcall = XCAR (pending_funcalls);
4722 pending_funcalls = XCDR (pending_funcalls);
4723 safe_calln (Qapply, XCAR (funcall), XCDR (funcall));
4724 }
4725
4726 unbind_to (count, Qnil);
4716 } 4727 }
4717 4728
4718 if (! (CONSP (timers) || CONSP (idle_timers))) 4729 if (! (CONSP (timers) || CONSP (idle_timers)))
@@ -4811,7 +4822,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4811 if (NILP (AREF (chosen_timer, 0))) 4822 if (NILP (AREF (chosen_timer, 0)))
4812 { 4823 {
4813 specpdl_ref count = SPECPDL_INDEX (); 4824 specpdl_ref count = SPECPDL_INDEX ();
4814 Lisp_Object old_deactivate_mark = Vdeactivate_mark; 4825 specbind (Qdeactivate_mark, Vdeactivate_mark);
4815 4826
4816 /* Mark the timer as triggered to prevent problems if the lisp 4827 /* Mark the timer as triggered to prevent problems if the lisp
4817 code fails to reschedule it right. */ 4828 code fails to reschedule it right. */
@@ -4820,7 +4831,6 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4820 specbind (Qinhibit_quit, Qt); 4831 specbind (Qinhibit_quit, Qt);
4821 4832
4822 calln (Qtimer_event_handler, chosen_timer); 4833 calln (Qtimer_event_handler, chosen_timer);
4823 Vdeactivate_mark = old_deactivate_mark;
4824 timers_run++; 4834 timers_run++;
4825 unbind_to (count, Qnil); 4835 unbind_to (count, Qnil);
4826 4836