TPromise races and squeak incompatibility

Previous Topic Next Topic
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

TPromise races and squeak incompatibility

Georg Köster
Hi all,

I'm toying with Croquet since a short time. It's really a neat idea - thanks for putting this up!

In my trials I found that TPromise is buggy - so here's a fix and a test.

Main issue: Timed waiting via TPromise>>waitTimeoutMSecs fails to return when isResolved is true in 90 % of (my) cases. Reason:
waitTimeoutMSecs: msecs
    "Wait for at most the given number of milliseconds for this promise to resolve. Answer true if it is resolved, false otherwise."
    | sema |
    sema := Semaphore new.
    self whenComplete:[sema signal].
    Delay timeoutSemaphore: sema afterMSecs: msecs.
  "BUG: where's the 'sema wait' ?"
    ^self isResolved

But troubles don't stop there. This simple pseudo-fix introduces a race because isResolved is set after the execution of the whenComplete block (the 'resolver' block). So isResolved might well be false still if the process executing the resolver is preempted after the 'sema signal' and before the 'resolved := true'. See here:
onResolved: arg
    "Resolve this promise"
    self unregister.
    result := arg.
    resolver ifNotNil:[
        resolver numArgs = 0 ifTrue:[resolver value]. "this is the execution of the resolver block."
        resolver numArgs = 1 ifTrue:[resolver value: arg].
        resolver := nil.
    resolved := true.

So I introduced a new hook, afterResolvingHook, that is used exclusively by the two wait methods.

I had some special trouble with Delay>>timeoutSemaphore:afterMSecs: on my image. It never signaled my Semaphore and the whole image locked up. But that doesn't happen on a new image.
Question here is: Why don't we use Semaphore>>waitTimeoutMSecs: which diverts to Delay? My code uses the Semaphore method.

What are your comments? Did I miss something here?

Georg (5K) Download Attachment (1K) Download Attachment