Fix race condition when waiting for SIGCHLD.
authorStefan Vogel <sv@exept.de>
Tue, 25 Mar 1997 13:50:51 +0100
changeset 2499 95392696facc
parent 2498 eb0bad72f05e
child 2500 c217e646447e
Fix race condition when waiting for SIGCHLD.
ProcSched.st
ProcessorScheduler.st
--- 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!