Water 5-Concurrent Programming-Thread
method thread.wait_until_condition
Contract
Return typewob
Parameter keyDefault valueType
a_lockreqthing
conditionreq with ekind of expressionwob
Parameter kindDefault valueType
Other unkeyed argumentsopt with ekind of stringstring
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.