diff options
| author | Daniel Colascione | 2025-06-10 11:39:19 -0700 |
|---|---|---|
| committer | Daniel Colascione | 2025-06-10 11:45:58 -0700 |
| commit | 57b5be4eb9afe819bf67c73afc4d330dd3aacac2 (patch) | |
| tree | ee3ecda6fc650d170422899184e790b90750c3b1 | |
| parent | da92ad2eaa151b2f5865e6d9bc95fa7009860bd8 (diff) | |
| download | emacs-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.c | 22 |
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 | |||
| 4708 | timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | 4708 | timer_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 | ||