diff options
-rw-r--r-- | scsh-process.scm | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/scsh-process.scm b/scsh-process.scm index e2be39c..4153c00 100644 --- a/scsh-process.scm +++ b/scsh-process.scm @@ -115,7 +115,12 @@ (error 'process-wait "Not a scsh-type process object or pid" pid-or-process)) - (let ((p (if (and pid-or-process (number? pid-or-process)) + ;; We need to make a copy because when waiting for #f, we + ;; can't predict which pid we'll receive, and the SIGCHLD + ;; handler will drop the pid from the pending list. + (let ((pending-before + (hash-table-copy *scsh-pending-processes*)) + (p (if (and pid-or-process (number? pid-or-process)) (hash-table-ref/default *scsh-pending-processes* pid-or-process #f) pid-or-process))) @@ -138,16 +143,21 @@ (scsh-process-pid p)) (abort exn)) (receive (pid ok? status) - (posix-process-wait (and p (scsh-process-pid p)) nohang) + (posix-process-wait (if p + (scsh-process-pid p) + pid-or-process) nohang) (cond ((zero? pid) (values #f #f #f)) - (else (when p - (scsh-process-exit-status-set! p status) - (scsh-process-ok?-set! p ok?) - (condition-variable-broadcast! - (scsh-process-child-condition p))) - (remove-scsh-pending-process! pid) - (values status ok? pid)))))))))) + (else + (and-let* ((p (or p (hash-table-ref/default + pending-before pid #f)))) + (scsh-process-exit-status-set! p status) + (scsh-process-ok?-set! p ok?) + (condition-variable-broadcast! + (scsh-process-child-condition p))) + + (remove-scsh-pending-process! pid) + (values status ok? pid)))))))))) (set-signal-handler! signal/chld @@ -163,7 +173,7 @@ (for-each (lambda (pid) (handle-exceptions exn ;; User might have waited manually - (begin (remove-scsh-pending-process! pid) (void)) + (begin (remove-scsh-pending-process! pid) (void)) (receive (pid ok? status) (posix-process-wait pid #t) (unless (zero? pid) |