#BUGFIX by stefan
authorStefan Vogel <sv@exept.de>
Thu, 29 Mar 2018 16:21:22 +0200
changeset 22662 dd7deac2fcd5
parent 22661 7e1478f7a9e3
child 22663 0f063640f797
#BUGFIX by stefan class: ProcessorScheduler changed: #handleChildSignalInterrupt (send #blockingChildProcessWait instead of #isChildProcessWaitBlocking) #monitor:action: Fix race condition when more than a single subprocess is forked and exitimg at a time.
ProcessorScheduler.st
--- a/ProcessorScheduler.st	Thu Mar 29 13:05:39 2018 +0200
+++ b/ProcessorScheduler.st	Thu Mar 29 16:21:22 2018 +0200
@@ -1175,7 +1175,8 @@
 
     |osProcessStatus blocking wasBlocked|
 
-    blocking := OperatingSystem isChildProcessWaitBlocking.
+    "/ blocking waits are no longer supported - see ProcessorScheduler>>#monitor:action:
+    blocking := OperatingSystem blockingChildProcessWait.
 
     "/ no interrupt processing, to avoid races with monitorPid
     wasBlocked := OperatingSystem blockInterrupts.
@@ -1213,9 +1214,9 @@
         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
     ]
 
-    "Modified: 5.1.1996 / 16:56:11 / stefan"
-    "Modified: 28.2.1996 / 21:36:31 / cg"
-    "Created: 12.4.1996 / 10:08:21 / stefan"
+    "Modified: / 28-02-1996 / 21:36:31 / cg"
+    "Created: / 12-04-1996 / 10:08:21 / stefan"
+    "Modified: / 29-03-2018 / 16:00:34 / stefan"
 !
 
 monitor:aBlockReturningPid action:actionBlock
@@ -1228,7 +1229,7 @@
      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 wasBlocked exitStatus|
+    |pid waitedForactionBlock wasBlocked osProcessStatus|
 
     "/ aBlock will be evaluated:
     "/   on unix: as soon as a SIGCHLD interrupt for pid has been received.
@@ -1241,20 +1242,27 @@
     pid notNil ifTrue:[
         osChildExitActions at:pid put:actionBlock.
         "check for a race, that SIGCHILD was received before we could register the actionBlock"
-        exitStatus := OperatingSystem childProcessWait:false pid:pid.
-        exitStatus notNil ifTrue:[
-            self unmonitorPid:pid.
-            wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
-            actionBlock value:exitStatus.
+        osProcessStatus := OperatingSystem childProcessWait:false pid:pid.
+        osProcessStatus notNil ifTrue:[
+            "be careful, some implementations of #childProcessWait:pid:
+             (wait() and wait3() in very old unixes) wait for any pid!!"
+            osProcessStatus stillAlive ifTrue:[
+                waitedForactionBlock := osChildExitActions at:pid ifAbsent:nil.
+            ] ifFalse:[
+                waitedForactionBlock := osChildExitActions removeKey:pid ifAbsent:nil.
+            ].
+            waitedForactionBlock notNil ifTrue:[
+                waitedForactionBlock value:osProcessStatus
+            ].
         ].
     ].
     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
     ^ pid
 
-    "Created: / 25.3.1997 / 10:54:56 / stefan"
-    "Modified: / 25.3.1997 / 11:21:05 / stefan"
-    "Modified: / 15.4.1997 / 11:55:57 / David"
-    "Modified: / 27.4.1999 / 20:09:38 / cg"
+    "Created: / 25-03-1997 / 10:54:56 / stefan"
+    "Modified: / 15-04-1997 / 11:55:57 / David"
+    "Modified: / 27-04-1999 / 20:09:38 / cg"
+    "Modified (format): / 29-03-2018 / 15:53:53 / stefan"
 !
 
 unmonitorPid:pid