diff options
author | Ludovic Courtès <ludo@gnu.org> | 2020-02-23 18:49:52 +0100 |
---|---|---|
committer | Dale Mellor <black-hole@rdmp.org> | 2020-02-27 21:03:47 +0000 |
commit | 8ae1e8c92e88308a6f1a7107acdf17e5526d4e89 (patch) | |
tree | 61660715a7b8c20eea98d984c83c24f22b7e0d0f /src/mcron | |
parent | bedec44b397179c0eb1d11e52d0a6105015f6e38 (diff) | |
download | mcron-8ae1e8c92e88308a6f1a7107acdf17e5526d4e89.tar.gz mcron-8ae1e8c92e88308a6f1a7107acdf17e5526d4e89.tar.bz2 mcron-8ae1e8c92e88308a6f1a7107acdf17e5526d4e89.zip |
base: Call 'child-cleanup' when 'select' returns an empty set.
Previously, on Guile >= 2.2, we'd lose this opportunity to call
'child-cleanup', possibly leaving zombies behind us.
* src/mcron/base.scm (run-job-loop): Define 'select*'. Don't expect
'select*' to throw upon EINTR or EAGAIN.
Diffstat (limited to 'src/mcron')
-rw-r--r-- | src/mcron/base.scm | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/mcron/base.scm b/src/mcron/base.scm index 17ddd5c..572d45b 100644 --- a/src/mcron/base.scm +++ b/src/mcron/base.scm @@ -1,7 +1,7 @@ ;;;; base.scm -- core procedures ;;; Copyright © 2003 Dale Mellor <dale_mellor@users.sourceforge.net> ;;; Copyright © 2015, 2016, 2018 Mathieu Lirzin <mthl@gnu.org> -;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2016, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Mcron. ;;; @@ -210,6 +210,20 @@ next value." ;; case we break out of the loop here, and let the main procedure deal with ;; the situation (it will eventually re-call this function, thus maintaining ;; the loop). + (cond-expand + ((or guile-3.0 guile-2.2) ;2.2 and 3.0 + (define select* select)) + (else + ;; On Guile 2.0, 'select' could throw upon EINTR or EAGAIN. + (define (select* read write except time) + (catch 'system-error + (lambda () + (select read write except time)) + (lambda args + (if (member (system-error-errno args) (list EAGAIN EINTR)) + '(() () ()) + (apply throw args))))))) + (call-with-current-continuation (lambda (break) (let loop () @@ -218,19 +232,17 @@ next value." (let ((sleep-time (if next-time (- next-time (current-time)) 2000000000))) - (when (and - (> sleep-time 0) - (not (null? (catch 'system-error - (λ () - (car (select fd-list '() '() sleep-time))) - (λ (key . args) - (let ((err (car (last args)))) - (cond ((member err (list EINTR EAGAIN)) - (child-cleanup) - '()) - (else - (apply throw key args))))))))) - (break)) + (when (> sleep-time 0) + (match (select* fd-list '() '() sleep-time) + ((() () ()) + ;; 'select' returned an empty set, perhaps because it got + ;; EINTR or EAGAIN. It's a good time to wait for child + ;; processes. + (child-cleanup)) + (((lst ...) () ()) + ;; There's some activity so leave the loop. + (break)))) + (for-each run-job next-jobs-lst) (child-cleanup) (loop)))))))) |