[squeak-dev] Another interesting behavior of Delay

Igor Stasenko siguctua at gmail.com
Tue Sep 22 04:58:53 UTC 2009


I just found that its risky to use same instance of Delay, to wait by
more than single process.

| d sema t1 t2 first  |
 d := Delay forMilliseconds: 200.
sema := Semaphore new.
first := nil.
[ t1 := [ d wait. first ifNil: [ first := true]. ] timeToRun.  sema
signal ] forkAt: Processor activePriority +1.

[ (Delay forMilliseconds: 100) wait.
   t2 := [ d wait. first ifNil: [first := false]. ] timeToRun. sema
signal ] forkAt: Processor activePriority +1.

sema wait.
sema wait.

{ t1. t2. first.  }

both values, t1, t2 should be around 200 ms , because both processes
waiting for same delay, right?
But code always returns #(300 200 true)

Of course, delay not guarantees that time elapsed will be the same as
requested, because some higher priority process
could simply prevent from activating the process with elapsed delay.
But in given code, there is no such process.

The 'first' flag is true, which means that process, who created first,
gaining control after waiting on delay before second process,
which makes things even more odd, because scheduling the same delay
for a second time should not change the awake time of first one.

The main reason , why i would want to reuse same delay instance, is to
conserve space and not produce the garbage
by creating a new Delay instance each time i want to put delay:

"at some initialization "
MyDelayClassVar := Delay forMilliseconds: 100.


and then somewhere in another method:

someMethod
   x to: y do: [ self doSomeThing. MyDelayClassVar  wait. ]

and as i illustrated, if #someMethod used by multiple processes, it
starts behaving interestingly :)

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list