# HG changeset patch # User Stefan Vogel # Date 859294251 -3600 # Node ID 95392696facc0d928ddbdbf874ff39570426eba0 # Parent eb0bad72f05ecee938a0bd9b1417444b77709366 Fix race condition when waiting for SIGCHLD. diff -r eb0bad72f05e -r 95392696facc ProcSched.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! diff -r eb0bad72f05e -r 95392696facc ProcessorScheduler.st --- 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!