guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[shepherd] 03/09: Use Fibers.


From: Ludovic Courtès
Subject: [shepherd] 03/09: Use Fibers.
Date: Wed, 23 Mar 2022 18:26:33 -0400 (EDT)

civodul pushed a commit to branch wip-fibers
in repository shepherd.

commit 934204fbd158aa9fbd42914b89aa960f99eef125
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Mon Mar 21 10:20:23 2022 +0100

    Use Fibers.
    
    * configure.ac: Add 'GUILE_MODULE_AVAILABLE' use for Fibers.
    Add 'AC_CACHE_CHECK' use for 'ac_cv_fibers_creates_pthreads'.
    * modules/shepherd.scm: Use (fibers).
    (signal-handler): In the SIGTERM/SIGHUP case, catch 'quit.
    (main): Wrap call to 'run-daemon' in 'run-fibers'.
    (quit-exception-handler): Call 'primitive-exit' in the default case.
---
 configure.ac         | 25 +++++++++++++++++++++++++
 modules/shepherd.scm | 29 +++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index ac6493d..f98dbb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,6 +33,31 @@ 
guileobjectdir="${libdir}/guile/$GUILE_EFFECTIVE_VERSION/site-ccache"
 AC_SUBST([guilemoduledir])
 AC_SUBST([guileobjectdir])
 
+dnl Check for extra dependencies.
+GUILE_MODULE_AVAILABLE([have_fibers], [(fibers)])
+if test "x$have_fibers" != "xyes"; then
+  AC_MSG_ERROR([Fibers is missing; please install it.])
+fi
+
+dnl Make sure Fibers does not create POSIX threads: since shepherd
+dnl forks, it must be single-threaded.
+AC_CACHE_CHECK([whether Fibers might create POSIX threads],
+  [ac_cv_fibers_creates_pthreads],
+  [GUILE_CHECK([retval],
+    [(use-modules (fibers))
+     (set! (@ (ice-9 threads) call-with-new-thread)
+       (lambda _ (throw 'new-thread!)))
+     (run-fibers (lambda () (spawn-fiber (lambda () 1)))
+                 #:parallelism 1 #:hz 0)])
+   if test "$retval" = 0; then
+     ac_cv_fibers_creates_pthreads="no"
+   else
+     ac_cv_fibers_creates_pthreads="yes"
+   fi])
+if test "x$ac_cv_fibers_creates_pthreads" = "xyes"; then
+  AC_MSG_ERROR([Fibers creates POSIX threads behind our back; aborting.])
+fi
+
 dnl
 dnl Low-level operating system interface.
 dnl
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index 4365ca8..da2e509 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -20,6 +20,7 @@
 ;; along with the GNU Shepherd.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (shepherd)
+  #:use-module (fibers)
   #:use-module (ice-9 match)
   #:use-module (ice-9 format)
   #:use-module (ice-9 rdelim)   ;; Line-based I/O.
@@ -107,7 +108,11 @@ already ~a threads running, disabling 'signalfd' support")
         ((= signal SIGINT)
          (lambda _ (handle-SIGINT)))
         ((memv signal (list SIGTERM SIGHUP))
-         (lambda _ (stop root-service)))
+         (lambda _
+           (catch 'quit
+             (lambda ()
+               (stop root-service))
+             quit-exception-handler)))
         (else
          (const #f))))
 
@@ -366,12 +371,18 @@ already ~a threads running, disabling 'signalfd' support")
                   (sigaction signal (signal-handler signal)))
                 (delete SIGCHLD %precious-signals))
 
-      (run-daemon #:socket-file socket-file
-                  #:config-file config-file
-                  #:pid-file pid-file
-                  #:signal-port signal-port
-                  #:poll-services? poll-services?
-                  #:persistency persistency))))
+      ;; Run Fibers in such a way that it does not create any POSIX thread,
+      ;; because POSIX threads and 'fork' cannot be used together.
+      (run-fibers
+       (lambda ()
+         (run-daemon #:socket-file socket-file
+                     #:config-file config-file
+                     #:pid-file pid-file
+                     #:signal-port signal-port
+                     #:poll-services? poll-services?
+                     #:persistency persistency))
+       #:parallelism 1  ;don't create POSIX threads
+       #:hz 0))))       ;disable preemption, which would require POSIX threads
 
 ;; Start all of SERVICES, which is a list of canonical names (FIXME?),
 ;; but in a order where all dependencies are fulfilled before we
@@ -420,7 +431,9 @@ already ~a threads running, disabling 'signalfd' support")
       (begin
         (local-output (l10n "Rebooting..."))
         (reboot))
-      (quit)))
+      (begin
+        (local-output (l10n "Exiting."))
+        (primitive-exit 0))))              ;leave without going through Fibers
 
 (define (process-command command port)
   "Interpret COMMAND, a command sent by the user, represented as a



reply via email to

[Prev in Thread] Current Thread [Next in Thread]