[Pharo-project] Example of non-concurrent code :)

Igor Stasenko siguctua at gmail.com
Sat Oct 16 00:41:30 EDT 2010

mouseTrailFrom: currentBuf
	"Current event, a mouse event buffer, is about to be processed.  If
there are other similar mouse events queued up, then drop them from
the queue, and report the positions inbetween."

	| nextEvent trail |
	trail := (Array new: 1) writeStream.
	trail nextPut: currentBuf third @ currentBuf fourth.
*a*	[(nextEvent := Sensor peekEvent) isNil] whileFalse:
			[nextEvent first = currentBuf first
				ifFalse: [^trail contents	"different event type"].
			nextEvent fifth = currentBuf fifth
				ifFalse: [^trail contents	"buttons changed"].
			nextEvent sixth = currentBuf sixth
				ifFalse: [^trail contents	"modifiers changed"].
			"nextEvent is similar.  Remove it from the queue, and check the next."
*b*			nextEvent := Sensor nextEvent.
			trail nextPut: nextEvent third @ nextEvent fourth].
	^trail contents

Here, the bug:
first it sends #peekEvent and its not nil.
Okay, then after some logic voodo, it sends nextEvent, without
precaution, that it may also answer nil!

So, if some other process get between these two sends (*a*, *b*) and
fetch/flush all events, a code will fail,
'nextEvent third' is DNU , when nextEvent == nil.

The fix is simple:

nextEvent := Sensor nextEvent.
nextEvent ifNotNil: [ trail nextPut: nextEvent third @ nextEvent fourth]

Both Pharo & Squeak contain this bug. But this method slightly differs
from each other.

Best regards,
Igor Stasenko AKA sig.

More information about the Pharo-dev mailing list