summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scsh-process.scm49
1 files changed, 29 insertions, 20 deletions
diff --git a/scsh-process.scm b/scsh-process.scm
index 4153c00..4e6708d 100644
--- a/scsh-process.scm
+++ b/scsh-process.scm
@@ -221,26 +221,35 @@
(exit 0)))
(define (fork #!optional thunk continue-threads?)
- (let* ((maybe-reinstall-deadlock-workaround!
- (lambda ()
- (cond-expand
- (has-thread-killer
- (unless continue-threads? (install-deadlock-workaround!)))
- (else (void)))))
- (thunk (and thunk (lambda ()
- (clear-scsh-pending-processes!)
- (maybe-reinstall-deadlock-workaround!)
- (thunk))))
- (pid (cond-expand
- (has-thread-killer
- (process-fork thunk (not continue-threads?)))
- (else ;; Ignore both args if thunk is #f, so #f won't be applied
- (if thunk (process-fork thunk) (process-fork))))))
- (cond ((zero? pid)
- (clear-scsh-pending-processes!)
- (maybe-reinstall-deadlock-workaround!)
- #f)
- (else (add-scsh-pending-process! pid)))))
+ (dynamic-wind
+ ;; If we're really unlucky, sigchld might be delivered
+ ;; immediately after forking, but before we added the child's
+ ;; pid to the pending processes table. This means we'll lose
+ ;; the event and won't mark the process as finished, resulting
+ ;; in an endless loop in process-wait. So, mask it.
+ (lambda () (signal-mask! signal/chld))
+ (lambda ()
+ (let* ((maybe-reinstall-deadlock-workaround!
+ (lambda ()
+ (cond-expand
+ (has-thread-killer
+ (unless continue-threads? (install-deadlock-workaround!)))
+ (else (void)))))
+ (thunk (and thunk (lambda ()
+ (clear-scsh-pending-processes!)
+ (maybe-reinstall-deadlock-workaround!)
+ (thunk))))
+ (pid (cond-expand
+ (has-thread-killer
+ (process-fork thunk (not continue-threads?)))
+ (else ;; Ignore both args if thunk is #f, so #f won't be applied
+ (if thunk (process-fork thunk) (process-fork))))))
+ (cond ((zero? pid)
+ (clear-scsh-pending-processes!)
+ (maybe-reinstall-deadlock-workaround!)
+ #f)
+ (else (add-scsh-pending-process! pid)))))
+ (lambda () (signal-unmask! signal/chld))))
(define %fork fork)