unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Interrupting computations using signals
@ 2021-05-24 12:32 Daniel Mendler
  2021-05-24 12:53 ` Eli Zaretskii
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Mendler @ 2021-05-24 12:32 UTC (permalink / raw)
  To: emacs-devel@gnu.org

If Emacs is running in GUI mode, I can interrupt computations by
pressing `C-g` (keyboard-quit). Is there also a possibility to submit
such an interrupt from outside, via signals or via another mechanism?

This feature would be useful when running computations in an external
Emacs worker process. Ideally there is some API which allows to enable
external interrupts only within an interruptible section. Note that I
can always terminate a worker process via the OS mechanisms, but that is
not the point here, I want to make it interruptible instead.

I've read something in the manual about SIGUSR1/SIGUSR2 but I could not
get these handlers to work in an Emacs running in daemon or batch mode.

Daniel



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

* Re: Interrupting computations using signals
  2021-05-24 12:32 Interrupting computations using signals Daniel Mendler
@ 2021-05-24 12:53 ` Eli Zaretskii
  2021-05-24 14:08   ` Daniel Mendler
  0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2021-05-24 12:53 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: emacs-devel

> From: Daniel Mendler <mail@daniel-mendler.de>
> Date: Mon, 24 May 2021 14:32:05 +0200
> 
> If Emacs is running in GUI mode, I can interrupt computations by
> pressing `C-g` (keyboard-quit). Is there also a possibility to submit
> such an interrupt from outside, via signals or via another mechanism?

Yes, read about sigusr1 and sigusr2 in the ELisp manual.

> I've read something in the manual about SIGUSR1/SIGUSR2 but I could not
> get these handlers to work in an Emacs running in daemon or batch mode.

Show us the code.



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

* Re: Interrupting computations using signals
  2021-05-24 12:53 ` Eli Zaretskii
@ 2021-05-24 14:08   ` Daniel Mendler
  2021-05-24 14:37     ` Eli Zaretskii
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Mendler @ 2021-05-24 14:08 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 5/24/21 2:53 PM, Eli Zaretskii wrote:
>> I've read something in the manual about SIGUSR1/SIGUSR2 but I could not
>> get these handlers to work in an Emacs running in daemon or batch mode.
> 
> Show us the code.

I have a file "interrupt.el" containing this code:

~~~
(defun sigusr-handler ()
  (interactive)
  (message "Caught signal %S" last-input-event))

(define-key special-event-map [sigusr1] 'sigusr-handler)
(define-key special-event-map [sigusr2] 'sigusr-handler)

(condition-case nil
    (while t
      (with-local-quit
        (while t
          (sleep-for 0.1)))
      (message "QUIT"))
  (t (message "OUTER QUIT")))
~~~

1. I start the batch process with "emacs -Q --batch -l interrupt.el" or
"emacs -Q --fg-daemon -l interrupt.el".

2. I send a SIGUSR1 signal to the process. The signal is ignored.
Nothing happens, in particular the handler is not called.

3. I send a SIGUSR2 signal to the process. The process terminates with
the message "Debugger entered--beginning evaluation of function call
form: * (setq quit-flag t)...". I neither see the "QUIT" nor the "OUTER
QUIT" message.

Daniel



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

* Re: Interrupting computations using signals
  2021-05-24 14:08   ` Daniel Mendler
@ 2021-05-24 14:37     ` Eli Zaretskii
  2021-05-24 15:12       ` Daniel Mendler
  0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2021-05-24 14:37 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: emacs-devel

> Cc: emacs-devel@gnu.org
> From: Daniel Mendler <mail@daniel-mendler.de>
> Date: Mon, 24 May 2021 16:08:07 +0200
> 
> I have a file "interrupt.el" containing this code:
> 
> ~~~
> (defun sigusr-handler ()
>   (interactive)
>   (message "Caught signal %S" last-input-event))
> 
> (define-key special-event-map [sigusr1] 'sigusr-handler)
> (define-key special-event-map [sigusr2] 'sigusr-handler)
> 
> (condition-case nil
>     (while t
>       (with-local-quit
>         (while t
>           (sleep-for 0.1)))
>       (message "QUIT"))
>   (t (message "OUTER QUIT")))
> ~~~
> 
> 1. I start the batch process with "emacs -Q --batch -l interrupt.el" or
> "emacs -Q --fg-daemon -l interrupt.el".
> 
> 2. I send a SIGUSR1 signal to the process. The signal is ignored.
> Nothing happens, in particular the handler is not called.
> 
> 3. I send a SIGUSR2 signal to the process. The process terminates with
> the message "Debugger entered--beginning evaluation of function call
> form: * (setq quit-flag t)...". I neither see the "QUIT" nor the "OUTER
> QUIT" message.

See the documentation of debug-on-event to understand the effect of
SIGUSR2.

As for the effect of SIGUSR1, I think that at least part of the issue
is that you never give Emacs the chance to read the sigusr1 "key".  As
you see from the example in the ELisp manual that you copied, this
feature works by generating an input event, but if Emacs doesn't read
input, it will never pay attention.

I guess this is where you tell more about your use case, so that we
could understand why, for example, what SIGUSR2 does is not what you
wanted.



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

* Re: Interrupting computations using signals
  2021-05-24 14:37     ` Eli Zaretskii
@ 2021-05-24 15:12       ` Daniel Mendler
  2021-05-24 16:34         ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Mendler @ 2021-05-24 15:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 5/24/21 4:37 PM, Eli Zaretskii wrote:
> See the documentation of debug-on-event to understand the effect of
> SIGUSR2.

Thank you Eli! `debug-on-event`was exactly what I was looking for. This
way I can define an `interruptible` macro, which is only effective
around interruptible sections of code.

Daniel

~~~
;; Disable debugger
(setq debug-on-event nil)
(advice-add #'debug :around #'ignore)

;; Interruptible sections
(defmacro interruptible (&rest body)
  `(condition-case err
       (let ((debug-on-event 'sigusr2)) ,@body)
     (quit nil)))

;; Example
(while t
  (interruptible
   (message "COMPUTE")
   (sleep-for 1)
   (message "COMPUTE-END")))
~~~



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

* Re: Interrupting computations using signals
  2021-05-24 15:12       ` Daniel Mendler
@ 2021-05-24 16:34         ` Stefan Monnier
  0 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2021-05-24 16:34 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: Eli Zaretskii, emacs-devel

> (advice-add #'debug :around #'ignore)

Side note: it would be more honest to use `:override` here.


        Stefan




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

end of thread, other threads:[~2021-05-24 16:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-24 12:32 Interrupting computations using signals Daniel Mendler
2021-05-24 12:53 ` Eli Zaretskii
2021-05-24 14:08   ` Daniel Mendler
2021-05-24 14:37     ` Eli Zaretskii
2021-05-24 15:12       ` Daniel Mendler
2021-05-24 16:34         ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).