linux-container: Ensure signal-handling asyncs get a chance to run.

Previously we could enter the blocking 'waitpid' call and miss an
opportunity to run the signal handler async.

* gnu/build/linux-container.scm (call-with-container)
[periodically-schedule-asyncs]: New procedure.
[install-signal-handlers]: Call it.
This commit is contained in:
Ludovic Courtès 2022-04-27 17:53:10 +02:00
parent a76fa226c8
commit f6c9763984
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -327,11 +327,20 @@ (define* (call-with-container mounts thunk #:key (namespaces %namespaces)
Note that if THUNK needs to load any additional Guile modules, the relevant Note that if THUNK needs to load any additional Guile modules, the relevant
module files must be present in one of the mappings in MOUNTS and the Guile module files must be present in one of the mappings in MOUNTS and the Guile
load path must be adjusted as needed." load path must be adjusted as needed."
(define (periodically-schedule-asyncs)
;; XXX: In Guile there's a time window where a signal-handling async could
;; be queued without being processed by the time we enter a blocking
;; syscall like waitpid(2) (info "(guile) Signals"). This terrible hack
;; ensures pending asyncs get a chance to run periodically.
(sigaction SIGALRM (lambda _ (alarm 1)))
(alarm 1))
(define (install-signal-handlers pid) (define (install-signal-handlers pid)
;; Install handlers that forward signals to PID. ;; Install handlers that forward signals to PID.
(define (relay-signal signal) (define (relay-signal signal)
(false-if-exception (kill pid signal))) (false-if-exception (kill pid signal)))
(periodically-schedule-asyncs)
(for-each (lambda (signal) (for-each (lambda (signal)
(sigaction signal relay-signal)) (sigaction signal relay-signal))
relayed-signals)) relayed-signals))