Some more digging revealed a pending VW fix that might be related - it purports to fix a hole in Semaphore>>critical: and I wonder whether it might apply to Squeak as well.
Current Squeak implementation: critical: mutuallyExcludedBlock | blockValue | self wait. [blockValue _ mutuallyExcludedBlock value] ensure: [self signal]. ^blockValue
Current VisualWorks implementation: critical: mutuallyExcludedBlock self waitIfCurtailedSignal. ^mutuallyExcludedBlock ensure: [self signal]
Proposed fix (see http://tinyurl.com/9ed25): critical: mutuallyExcludedBlock | recover | recover := false. ^[ | result | self waitIfCurtailedSignal. "The dynamic translator creates code that can't be interrupted here (I think)." recover := true. result := mutuallyExcludedBlock value. recover := false. "The dynamic translator creates code that can't be interrupted here (I think)." self signal. result ] ifCurtailed: [ recover ifTrue: [ recover := false. self signal]].
The fix has some test code in its comment (again, see the tinyurl) that I'm going to run now, but I was wondering whether people could comment on the applicability to Squeak of this fix. In VW, it seems to make a difference...
On 1/5/06, Cees De Groot cdegroot@gmail.com wrote:
Below a stack trace we've been seeing a couple of times lately in our wxSqueak project (which is mostly 3.8). It seems that SuspendedDelays has a nil element somewhere. However, the code in Delay seems to be safe against that and I can't see any code elsewhere in the image that messes around with delays...
Has anyone ever seen this?
UndefinedObject(Object)>>doesNotUnderstand: #resumptionTime [] in Delay class>>DoIt {[:t2 :t3 | t2 resumptionTime <= t3 resumptionTime]} SortedCollection>>indexForInserting: SortedCollection>>add: [] in Delay>>schedule {[beingWaitedOn := true. resumptionTime := Time millisecondClockValue + dela...]} [] in Semaphore>>critical: {[t2 := t1 value]} BlockContext>>ensure: Semaphore>>critical: Delay>>schedule Delay>>wait TUDispatchingDatagramChannel(TUDatagramChannel)>>retransmissionRun [] in TUDispatchingDatagramChannel(TUDatagramChannel)>>start {[self retransmissionRun]} BlockContext>>repeat [] in TUDispatchingDatagramChannel(TUDatagramChannel)>>start {[[self retransmissionRun] repeat]} [] in BlockContext>>newProcess {[self value. Processor terminateActive]}