Water 5-Concurrent Programming-ThreadContract| Return type | wob | | Parameter key | Default value | Type | | a_lock | req | thing | | condition | req with ekind of expression | wob | | Parameter kind | Default value | Type | | Other unkeyed arguments | opt with ekind of string | string | | Water Contract<method thread.wait_until_condition
a_lock =req=thing
condition=req=wob=ekind.expression
_other_unkeyed=opt=string=ekind.string="_body"/> | |
See also: check_condition
wait_until_condition causes the current thread to pause until
a lock is available and a water expression returns true.
Once those conditions are met, another expression is executed
and its value is returned.
wait_until_condition performs the Java "wait" functionality
plus the pattern that it is commonly used it.
It is used in conjunction with check_condition which
performs the Java "notify" functionality plus the pattern that
it is commonly used in.
Here's how it works:
You pass in a lock, which can be any object,
a condition expression and a content expression.
First wait_until_condition waits until the lock is available
because the body of the wait_until_condition code happens with
a Java "synchronize" (think Water's do_solo ).
When it is, the condition expression is executed.
If it returns false , then Java "wait" is called
which waits until the lock is notified.
This wait actually releases the lock so that other methods
using a do_solo with that lock can run.
They will be "notified" when the Water check_condition
method is called.
When the lock is notified, the condition expression in
our wait_until_condition call is executed again.
If it returns false again, we will again wait.
But if it returns non-false, then the content expression
is executed and wait_until_condition returns the value
of that expression.
First we have a trivial example just to get use to the behavior.
thread.<wait_until_condition a_lock="lock124" condition=true>
<echo "doing wuc content"/>
</> | "doing wuc content" |
In the above example, no other calls are using "lock124" so
wait_until_continue immediately proceeds to executing the
condition expression. Since this is true ,
wait_until_continue immediately proceeds to executing the
content expression. It returns the string "doing wuc content"
because echo returns the string that it prints.
Next we have a more realistic example.
Below we are initializing thing.wuc_test to false ,
then setting up a thread to wait until it becomes true .
thing.<set wuc_test=false/>
<thread id="myt">
<echo "myt execution before wuc in water"/>
thread.<wait_until_condition a_lock="lock125" condition=thing.wuc_test>
<echo "doing wuc content"/>
</>
<echo "myt execution after wuc in water"/>
</thread>
thread.of.myt.<start/>
When myt is started, it prints out "myt execution before wuc in water"
in the console, then it gets past the lock since no one else has the lock.
Then thing.wuc_test is executed and returns false so
myt pauses.
Next we call check_condition to have myt wake up and run its
condition again.
thread.<check_condition a_lock="lock125">
<echo "in check_condition"/>
</check_condition> | null |
check_condition grabs the lock, executes its content,
which just prints out "in check_condition" ,
then notifies the lock.
This causes myt to wake up and execute its condition.
Since that returns false , myt again waits for another notify.
Now we're ready to set wuc_test to true to get our paused code to run.
thread.<check_condition "lock125">
<echo "in check_condition2"/>
thing.<set wuc_test=true/>
</check_condition> | null |
Again the content of check_condition is executed.
This time, in addition to our echo call, we set wuc_test to true .
Then "lock125" is notified so myt wakes up and
executes its condition expression.
Now it returns true so wait_until_condition proceeds to
execute its content, echoing "doing wuc content"
which is also returns, but this value is thrown away.
Now that we've completed the call to wait_until_condition ,
myt continues on to execute its next expression,
<echo "myt execution after wuc in water"/>
After this call is done, myt is done and the thread stops.
Note that as soon as our call to check_condition
executes the last expression in its content,
the thread that it was executing in continues with its
next instruction in parallel with the notification of
the myt thread. On a one processor machine this is not literally
in parallel, but the operating system time-slices simulate
parallelism and you should model the behavior that way
to best understand the sequence of events.
© Copyright 2007 Clear Methods, Inc.