[squeak-dev] OSProcess and Cuis [Diagnosed]
RossBoylan at stanfordalumni.org
Thu Sep 2 21:48:23 UTC 2010
On Thu, 2010-09-02 at 14:20 -0700, Ross Boylan wrote:
> I'm getting errors trying to file OSProcess (the st file from
> OSProcess-dtl.56.mcz) into Cuis. I am trying to do this so I can run
> magma tests.
> I don't know if there's any chance of this working. In the image
> Smalltalk listBuiltinModules #('ExuperyPlugin 27 February 2009 (i)')
> Smalltalk listLoadedModules. #('UnixOSProcessPlugin 27 February 2009 (e)' 'SoundPlugin 27 February 2009 (e)' 'BitBltPlugin 8 April 2009 (e)' 'LargeIntegers v1.5 27 February 2009 (e)' 'MiscPrimitivePlugin 27 February 2009 (e)' 'SecurityPlugin 27 February 2009 (e)' 'FilePlugin 27 February 2009 (e)')
> So it looks as if the necessary plugin is there (Smalltalk vmVersion
> 'Pharo0.1 of 16 May 2008 [latest update: #10074]')
> I think there's a small bug in OSProcessAccessor
> class>>forThisOSProcess. I changed the last 2 lines to be
> oldAccessor ifNotNil:
> [oldAccessor release; finalize.].
> ^ ThisOSProcessAccessor := self concreteClass basicNew initialize]
> I added the ifNotNil: test; without it release fails because it is sent
> to an undefined object. The ifNotNil: test probably belongs earlier in
> the code, but this was enough to get it to run.
> However, the final initialize fails. It calls
> UnixOSProcessAccessor>>grimReaperProcess, which fails because grimReaper
> is nil. I notice the very last OSProcess changeset touched this method.
I think there are 2 separate problems. First, the parentheses are off.
I think they should be
"This is a process which waits for the death of a child OSProcess, and
informs any dependents of the change. Use SIGCHLD events if possible,
otherwise a Delay to poll for exiting child processes."
| event processSynchronizationDelay |
^ self canAccessSystem
[event := (self canAccessSystem and: [self canForwardExternalSignals])
ifTrue: [self sigChldSemaphore]
ifFalse: [Delay forMilliseconds: 200].
processSynchronizationDelay := Delay forMilliseconds: 20.
processSynchronizationDelay wait. "Avoids lost signals in heavy process switching"
self changed: #childProcessStatus] repeat] fork.].
"name selected to look reasonable in the process browser"
grimReaper name: ((ReadStream on: grimReaper hash asString) next: 5)
, ': the child OSProcess watcher']
I moved a parentheses from after 'OSProcess watcher' on the 3rd to last
line to after the fork. I also added "." after the ].
The second problem is that fork in Cuis does not return an object. This
is perhaps related to the bug that inspired the latest OSProcess
release. There's a very informative comment on the Cuis fork method:
"Create and schedule a Process running the code in the receiver."
"jmv - Do NOT answer the new process.
Most times, this methods returns before resuming the new process (if priority of new process is less
or equal than current). But it might return afterwards.
This means it is very dangerous to use the returned process in code that stores it in some variable
and checks for nil to start a new one. If this methods happens to return after the new process is forked,
chances are the code that starts all this runs again, that variable is nil, and a second process is forked,
perhaps breaking some shared state. This kind of bug is hard to spot and debug.
Callers wanting the new process object, should call #newProcess, store the answer, and then #resume.
A way to ensure this bug will not ever happen again is just to answer nil"
self newProcess resume.
I think the fix is to do that (newProcess and resume), but perhaps this
means some of the syncronization code in the current grimReaperProcess
P.S. The original error arose when grimReaper name: failed.
More information about the Squeak-dev