[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Question about handling SIGINT properly in Guile
From: |
Olivier Dion |
Subject: |
Re: Question about handling SIGINT properly in Guile |
Date: |
Sat, 13 Apr 2024 12:46:04 -0400 |
On Sat, 13 Apr 2024, Vijay Marupudi <vijaymarupudi@gatech.edu> wrote:
> Hello folk of guile-user,
>
> I am trying to create a simple Guile program that continues to perform a
> task until an interrupt signal is sent. However, I am unable to
> deterministically end the program when SIGINT is sent, as the
> interrupt handler does not run soon after the call to (sleep ...) ends.
>
> Try running the simple reproduction included below. Try typing ^C
> (Ctrl+C) soon after the program begins. Sometimes "WORK" is run
> once, and sometimes "WORK" is run twice. What do I need to do to make
> "WORK" run only once in this instance?
Depending where the signal is sent, you will have two WORKs. For
example:
--8<---------------cut here---------------start------------->8---
(define quit? #f)
(sigaction SIGINT (lambda (arg)
(pk "SIG" arg)
(set! quit? #t)))
(let loop ()
(pk "QUIT-CHECK")
(if quit?
(begin (format #t "Quitting!~%") (exit 0))
(begin (pk "WORK" (do ((i 0 (+ i 1))
(sum 0 (+ sum i)))
((= i 1000) sum)))
(pk "SLEEP" (sleep 10))
(kill (getpid) SIGINT) ;; Ctrl-C emulation.
(loop))))
--8<---------------cut here---------------end--------------->8---
> I understand that signal handlers are asynchronous (Asyncs) and aren't
> guaranteed to run immediately. However, I expect them to be run before
> the next primitive call. Am I doing something wrong?
So there is two things with signals. First, when a process get a signal
queued, the OS only deliver the signal -- at least on linux -- when
going back to user-space. Typically, before the process get
re-scheduled or after a system call. So sending a signal is not
immediate. Furthermore, Guile also queues the signals and deliver them
to threads with async marks I think.
--
Olivier Dion
oldiob.ca