subprocess?
subprocess-index
set-subprocess-index!))
+ (set! subprocess-support-loaded? #t)
(reset-package!)
(add-event-receiver! event:after-restore reset-package!)
(add-event-receiver! event:before-exit delete-all-processes))
((3) 'JOB-CONTROL)
(else (error "Illegal process job-control status:" n)))))
\f
+;;;; Subprocess Events
+
+(define-structure (subprocess-registration
+ (conc-name subprocess-registration/))
+ (subprocess #f read-only #t)
+ (status #f)
+ (thread () read-only #t)
+ (event () read-only #t))
+
+(define (guarantee-subprocess-registration object procedure)
+ (if (not (subprocess-registration? object))
+ (error:wrong-type-argument object "subprocess-registration" procedure)))
+
+(define (guarantee-subprocess object procedure)
+ (if (not (subprocess? object))
+ (error:wrong-type-argument object "subprocess" procedure)))
+
+(define (register-subprocess-event subprocess status thread event)
+ (guarantee-subprocess subprocess 'register-subprocess-event)
+ (guarantee-thread thread 'register-subprocess-event)
+ (guarantee-procedure-of-arity event 1 'register-subprocess-event)
+ (let ((registration (make-subprocess-registration
+ subprocess status thread event)))
+ (with-thread-lock
+ (lambda ()
+ (set! subprocess-registrations
+ (cons registration subprocess-registrations))
+ (let ((current (subprocess-status subprocess)))
+ (if (not (eq? status current))
+ (begin
+ (%signal-thread-event
+ thread (and event (lambda () (event current))))
+ (set-subprocess-registration/status! registration current))))))
+ registration))
+
+(define (deregister-subprocess-event registration)
+ (guarantee-subprocess-registration registration
+ 'DEREGISTER-SUBPROCESS-EVENT)
+ (with-thread-lock
+ (lambda ()
+ (set! subprocess-registrations
+ (delq! registration subprocess-registrations)))))
+
+(define (deregister-subprocess subprocess delete-subprocess!)
+ (let ((error?
+ (with-thread-lock
+ (lambda ()
+ (set! subprocess-registrations
+ (filter!
+ (lambda (registration)
+ (not (eq? subprocess (subprocess-registration/subprocess
+ registration))))
+ subprocess-registrations))
+ (ignore-errors
+ (lambda ()
+ (delete-subprocess!)
+ #f))))))
+ (if error?
+ (signal-condition error?))))
+
+(define (deregister-subprocess-events thread)
+ (set! subprocess-registrations
+ (filter!
+ (lambda (registration)
+ (not (eq? thread (subprocess-registration/thread registration))))
+ subprocess-registrations)))
+\f
(define (handle-subprocess-status-change)
(with-thread-lock %handle-subprocess-status-change)
(if (eq? 'NT microcode-id/operating-system)
(if subprocess
(%poll-subprocess-status subprocess))))
(gc-finalizer-items subprocess-finalizer))
- (%signal-subprocess-status-change))))
+ (for-each
+ (lambda (registration)
+ (let ((status (subprocess-status
+ (subprocess-registration/subprocess registration)))
+ (old (subprocess-registration/status registration)))
+ (if (not (eq? status old))
+ (let ((event (subprocess-registration/event registration)))
+ (%signal-thread-event
+ (subprocess-registration/thread registration)
+ (and event (lambda () (event status))))
+ (set-subprocess-registration/status! registration
+ status)))))
+ subprocess-registrations)
+ (set! subprocess-registrations
+ (filter! (lambda (registration)
+ (let ((status
+ (subprocess-registration/status registration)))
+ (not (or (eq? status 'EXITED)
+ (eq? status 'SIGNALLED)))))
+ subprocess-registrations)))))
(define-integrable subprocess-job-control-available?
(ucode-primitive os-job-control? 0))
(else))
(parent (runtime))
(export ()
+ deregister-subprocess-event
make-subprocess
process-environment-bind
+ register-subprocess-event
run-subprocess-in-foreground
scheme-subprocess-environment
start-batch-subprocess
(export (runtime socket)
handle-subprocess-status-change)
(export (runtime thread)
+ deregister-subprocess-events
%handle-subprocess-status-change)
(import (runtime thread)
- with-thread-lock
- deregister-subprocess
- %signal-subprocess-status-change)
+ %signal-thread-event
+ subprocess-registrations
+ subprocess-support-loaded?
+ with-thread-lock)
(import (runtime gc-finalizer)
gc-finalizer-items
remove-from-locked-gc-finalizer!
deregister-gc-event
deregister-io-descriptor-events
deregister-io-thread-event
- deregister-subprocess-event
deregister-timer-event
detach-thread
exit-current-thread
+ guarantee-thread
join-thread
lock-thread-mutex
make-thread-mutex
permanently-register-io-thread-event
register-gc-event
register-io-thread-event
- register-subprocess-event
register-timer-event
registered-gc-event
restart-thread
(set-thread/block-events?! thread block-events?))
(%maybe-toggle-thread-timer))))
\f
+;;;; Subprocess Events
+
+(define subprocess-registrations)
+(define subprocess-support-loaded? #f)
+
+(define (%deregister-subprocess-events thread)
+ (%assert-locked '%deregister-subprocess-events)
+ (if subprocess-support-loaded?
+ (deregister-subprocess-events thread)))
+\f
;;;; GC Events
(define gc-events '()) ;Weak alist of threads X events.
(loop (cdr alist))))
#f)))
\f
-;;;; Subprocess Events
-
-(define subprocess-registrations)
-
-(define-structure (subprocess-registration
- (conc-name subprocess-registration/))
- (subprocess #f read-only #t)
- (status #f)
- (thread () read-only #t)
- (event () read-only #t))
-
-(define (guarantee-subprocess-registration object procedure)
- (if (not (subprocess-registration? object))
- (error:wrong-type-argument object "subprocess-registration" procedure)))
-
-(define (guarantee-subprocess object procedure)
- (if (not (subprocess? object))
- (error:wrong-type-argument object "subprocess" procedure)))
-
-(define (register-subprocess-event subprocess status thread event)
- (guarantee-subprocess subprocess 'register-subprocess-event)
- (guarantee-thread thread 'register-subprocess-event)
- (guarantee-procedure-of-arity event 1 'register-subprocess-event)
- (let ((registration (make-subprocess-registration
- subprocess status thread event)))
- (with-thread-lock
- (lambda ()
- (set! subprocess-registrations
- (cons registration subprocess-registrations))
- (let ((current (subprocess-status subprocess)))
- (if (not (eq? status current))
- (begin
- (%signal-thread-event
- thread (and event (lambda () (event current))))
- (set-subprocess-registration/status! registration current))))))
- registration))
-
-(define (deregister-subprocess-event registration)
- (guarantee-subprocess-registration registration
- 'DEREGISTER-SUBPROCESS-EVENT)
- (with-thread-lock
- (lambda ()
- (set! subprocess-registrations
- (delq! registration subprocess-registrations)))))
-
-(define (deregister-subprocess subprocess delete-subprocess!)
- (let ((error?
- (with-thread-lock
- (lambda ()
- (set! subprocess-registrations
- (filter!
- (lambda (registration)
- (not (eq? subprocess (subprocess-registration/subprocess
- registration))))
- subprocess-registrations))
- (ignore-errors
- (lambda ()
- (delete-subprocess!)
- #f))))))
- (if error?
- (signal-condition error?))))
-
-(define (%deregister-subprocess-events thread)
- (%assert-locked '%deregister-subprocess-events)
- (set! subprocess-registrations
- (filter!
- (lambda (registration)
- (not (eq? thread (subprocess-registration/thread registration))))
- subprocess-registrations)))
-
-(define (%signal-subprocess-status-change)
- (%assert-locked '%signal-subprocess-status-change)
- (for-each
- (lambda (registration)
- (let ((status (subprocess-status
- (subprocess-registration/subprocess registration)))
- (old (subprocess-registration/status registration)))
- (if (not (eq? status old))
- (let ((event (subprocess-registration/event registration)))
- (%signal-thread-event
- (subprocess-registration/thread registration)
- (and event (lambda () (event status))))
- (set-subprocess-registration/status! registration status)))))
- subprocess-registrations)
- (set! subprocess-registrations
- (filter! (lambda (registration)
- (let ((status (subprocess-registration/status registration)))
- (not (or (eq? status 'EXITED)
- (eq? status 'SIGNALLED)))))
- subprocess-registrations)))
-\f
;;;; Timer Events
(define timer-records)