[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[shepherd] 04/04: shepherd: Honor ‘SHEPHERD_DISABLE_SIGNALFD’ variable,
From: |
Ludovic Courtès |
Subject: |
[shepherd] 04/04: shepherd: Honor ‘SHEPHERD_DISABLE_SIGNALFD’ variable, for tests. |
Date: |
Sun, 24 Dec 2023 09:06:18 -0500 (EST) |
civodul pushed a commit to branch main
in repository shepherd.
commit bb0f662917d4fe5d3f5a57ca9503b48a41826451
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Sun Dec 24 13:02:37 2023 +0100
shepherd: Honor ‘SHEPHERD_DISABLE_SIGNALFD’ variable, for tests.
* modules/shepherd.scm (maybe-signal-port): Honor
‘SHEPHERD_DISABLE_SIGNALFD’.
---
modules/shepherd.scm | 65 ++++++++++++++++++++++++++++++----------------------
1 file changed, 38 insertions(+), 27 deletions(-)
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index 6b22b22..c99d133 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -68,34 +68,45 @@ socket file at FILE-NAME upon exit of PROC. Return the
values of PROC."
(define (maybe-signal-port signals)
"Return a signal port for SIGNALS, using 'signalfd' on GNU/Linux, or #f if
that is not supported."
- (catch 'system-error
- (lambda ()
- (let ((port (signalfd -1 signals (logior SFD_CLOEXEC SFD_NONBLOCK))))
- ;; As per the signalfd(2) man page, block SIGNALS. The tricky bit is
- ;; that SIGNALS must be blocked for all the threads; new threads will
- ;; inherit the signal mask, but we must ensure that neither Guile's
- ;; signal delivery thread nor its finalization thread are already
- ;; running, because if they do, they are not blocking SIGNALS. The
- ;; signal delivery thread is started on the first call to 'sigaction'
- ;; so we arrange to not call 'sigaction' beforehand; as for the
- ;; finalization thread, use 'without-automatic-finalization' to
- ;; temporarily stop it.
- (without-automatic-finalization
- (let ((count (length (all-threads))))
- (if (= 1 count)
- (begin
- (block-signals signals)
- port)
- (begin
- (local-output (l10n "warning: \
+ ;; Honor this environment variable for testing purposes: it lets us emulate
+ ;; the behavior on non-Linux systems.
+ (match (getenv "SHEPHERD_DISABLE_SIGNALFD")
+ ((or #f "0" "no")
+ (catch 'system-error
+ (lambda ()
+ (let ((port (signalfd -1 signals (logior SFD_CLOEXEC SFD_NONBLOCK))))
+ ;; As per the signalfd(2) man page, block SIGNALS. The tricky bit
is
+ ;; that SIGNALS must be blocked for all the threads; new threads
will
+ ;; inherit the signal mask, but we must ensure that neither Guile's
+ ;; signal delivery thread nor its finalization thread are already
+ ;; running, because if they do, they are not blocking SIGNALS. The
+ ;; signal delivery thread is started on the first call to
'sigaction'
+ ;; so we arrange to not call 'sigaction' beforehand; as for the
+ ;; finalization thread, use 'without-automatic-finalization' to
+ ;; temporarily stop it.
+ (without-automatic-finalization
+ (let ((count (length (all-threads))))
+ (if (= 1 count)
+ (begin
+ (block-signals signals)
+ port)
+ (begin
+ (local-output (l10n "warning: \
already ~a threads running, disabling 'signalfd' support")
- count)
- (close-port port)
- #f))))))
- (lambda args
- (if (= ENOSYS (system-error-errno args))
- #f
- (apply throw args)))))
+ count)
+ (close-port port)
+ #f))))))
+ (lambda args
+ (if (= ENOSYS (system-error-errno args))
+ (begin
+ (local-output
+ (l10n "System lacks support for 'signalfd'; \
+using fallback mechanism."))
+ #f)
+ (apply throw args)))))
+ (_
+ (local-output (l10n "Support for 'signalfd' is disabled."))
+ #f)))
(define (handle-SIGINT)
"Handle SIGINT by stopping the Shepherd, which means rebooting if we're PID
1."