Fix race condition when waiting for SIGCHLD.
--- a/ProcSched.st Tue Mar 25 13:48:30 1997 +0100
+++ b/ProcSched.st Tue Mar 25 13:50:51 1997 +0100
@@ -788,34 +788,52 @@
"Created: 12.4.1996 / 10:08:21 / stefan"
!
-monitorPid:pid action:aBlock
- "add a 1-arg-block that is called when the operating system child process
- with pid pid changes state.
- The argument for the block is an OSProcessStatus.
+monitor:aBlockReturningPid action:actionBlock
"
+ Helper for executing and waiting for OS processes.
+ aBlockReturningPid is evaluated and supposed to return
+ the process-id of an OS-process or nil.
+ To avoid race conditions, the OS-process must be started
+ within the block.
+
+ ActionBlock will be called with an OSProcessStatus as arg if the
+ status of the OS process changes (e.g. the process terminates).
+
+ The method returns the value from aBlockReturningPid (i.e a pid or nil).
+ "
+ |pid blocked osProcessStatus|
OperatingSystem sigCHLD ~= 0 ifTrue:[
- "/ SIGCHLD is supported,
- "/ aBlock will be evaluated, as soon as a SIGCHLD interrupt for pid has been received.
- OperatingSystem enableChildSignalInterrupts.
- osChildExitActions at:pid put:aBlock
+ "/ SIGCHLD is supported,
+ "/ aBlock will be evaluated, as soon as a SIGCHLD interrupt for pid has been received.
+ OperatingSystem enableChildSignalInterrupts.
+ blocked := OperatingSystem blockInterrupts.
+ pid := aBlockReturningPid value.
+ pid notNil ifTrue:[
+ osChildExitActions at:pid put:actionBlock.
+ ].
+ blocked ifFalse:[
+ OperatingSystem unblockInterrupts.
+ ].
] ifFalse:[
- |osProcessStatus|
- "/ SIGCHLD is not supported, wait synchronously for the exit
- "/ of pid.
- [
- osProcessStatus := OperatingSystem childProcessWait:true.
- osProcessStatus notNil ifTrue:[
- (osProcessStatus pid = pid) ifTrue:[
- aBlock value:osProcessStatus.
- ].
- osProcessStatus stillAlive
- ].
- ] whileTrue.
+ "/ SIGCHLD is not supported, wait synchronously for the exit
+ "/ of pid.
+
+ pid := aBlockReturningPid value.
+ [
+ osProcessStatus := OperatingSystem childProcessWait:true.
+ osProcessStatus notNil ifTrue:[
+ (osProcessStatus pid = pid) ifTrue:[
+ actionBlock value:osProcessStatus.
+ ].
+ osProcessStatus stillAlive
+ ].
+ ] whileTrue.
].
-
- "Created: 28.12.1995 / 14:22:10 / stefan"
- "Modified: 5.1.1996 / 22:01:06 / stefan"
+ ^ pid
+
+ "Created: 25.3.1997 / 10:54:56 / stefan"
+ "Modified: 25.3.1997 / 11:21:05 / stefan"
!
unmonitorPid:pid
@@ -2498,6 +2516,6 @@
!ProcessorScheduler class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Attic/ProcSched.st,v 1.124 1997-03-20 15:04:18 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/ProcSched.st,v 1.125 1997-03-25 12:50:51 stefan Exp $'
! !
ProcessorScheduler initialize!
--- a/ProcessorScheduler.st Tue Mar 25 13:48:30 1997 +0100
+++ b/ProcessorScheduler.st Tue Mar 25 13:50:51 1997 +0100
@@ -788,34 +788,52 @@
"Created: 12.4.1996 / 10:08:21 / stefan"
!
-monitorPid:pid action:aBlock
- "add a 1-arg-block that is called when the operating system child process
- with pid pid changes state.
- The argument for the block is an OSProcessStatus.
+monitor:aBlockReturningPid action:actionBlock
"
+ Helper for executing and waiting for OS processes.
+ aBlockReturningPid is evaluated and supposed to return
+ the process-id of an OS-process or nil.
+ To avoid race conditions, the OS-process must be started
+ within the block.
+
+ ActionBlock will be called with an OSProcessStatus as arg if the
+ status of the OS process changes (e.g. the process terminates).
+
+ The method returns the value from aBlockReturningPid (i.e a pid or nil).
+ "
+ |pid blocked osProcessStatus|
OperatingSystem sigCHLD ~= 0 ifTrue:[
- "/ SIGCHLD is supported,
- "/ aBlock will be evaluated, as soon as a SIGCHLD interrupt for pid has been received.
- OperatingSystem enableChildSignalInterrupts.
- osChildExitActions at:pid put:aBlock
+ "/ SIGCHLD is supported,
+ "/ aBlock will be evaluated, as soon as a SIGCHLD interrupt for pid has been received.
+ OperatingSystem enableChildSignalInterrupts.
+ blocked := OperatingSystem blockInterrupts.
+ pid := aBlockReturningPid value.
+ pid notNil ifTrue:[
+ osChildExitActions at:pid put:actionBlock.
+ ].
+ blocked ifFalse:[
+ OperatingSystem unblockInterrupts.
+ ].
] ifFalse:[
- |osProcessStatus|
- "/ SIGCHLD is not supported, wait synchronously for the exit
- "/ of pid.
- [
- osProcessStatus := OperatingSystem childProcessWait:true.
- osProcessStatus notNil ifTrue:[
- (osProcessStatus pid = pid) ifTrue:[
- aBlock value:osProcessStatus.
- ].
- osProcessStatus stillAlive
- ].
- ] whileTrue.
+ "/ SIGCHLD is not supported, wait synchronously for the exit
+ "/ of pid.
+
+ pid := aBlockReturningPid value.
+ [
+ osProcessStatus := OperatingSystem childProcessWait:true.
+ osProcessStatus notNil ifTrue:[
+ (osProcessStatus pid = pid) ifTrue:[
+ actionBlock value:osProcessStatus.
+ ].
+ osProcessStatus stillAlive
+ ].
+ ] whileTrue.
].
-
- "Created: 28.12.1995 / 14:22:10 / stefan"
- "Modified: 5.1.1996 / 22:01:06 / stefan"
+ ^ pid
+
+ "Created: 25.3.1997 / 10:54:56 / stefan"
+ "Modified: 25.3.1997 / 11:21:05 / stefan"
!
unmonitorPid:pid
@@ -2498,6 +2516,6 @@
!ProcessorScheduler class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.124 1997-03-20 15:04:18 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.125 1997-03-25 12:50:51 stefan Exp $'
! !
ProcessorScheduler initialize!