001: package org.jgroups.util;
002:
003: import org.jgroups.TimeoutException;
004:
005: /**
006: * Class that checks on a condition and - if condition doesn't match the expected result - waits until the result
007: * matches the expected result, or a timeout occurs. First version used WaitableBoolean from util.concurrent, but
008: * that class would not allow for timeouts.
009: * @author Bela Ban
010: * @version $Id: CondVar.java,v 1.3 2004/12/31 14:10:40 belaban Exp $
011: */
012: public class CondVar {
013: Object cond;
014: final String name;
015: final Object lock;
016:
017: public CondVar(String name, Object cond) {
018: this .name = name;
019: this .cond = cond;
020: lock = this ;
021: }
022:
023: public CondVar(String name, Object cond, Object lock) {
024: this .name = name;
025: this .cond = cond;
026: this .lock = lock;
027: }
028:
029: public Object get() {
030: synchronized (lock) {
031: return cond;
032: }
033: }
034:
035: /** Sets the result */
036: public void set(Object result) {
037: synchronized (lock) {
038: cond = result;
039: lock.notifyAll();
040: }
041: }
042:
043: public Object getLock() {
044: return lock;
045: }
046:
047: /**
048: * Waits until the condition matches the expected result. Returns immediately if they match, otherwise waits
049: * for timeout milliseconds or until the results match.
050: * @param result The result, needs to match the condition (using equals()).
051: * @param timeout Number of milliseconds to wait. A value of <= 0 means to wait forever
052: * @throws TimeoutException Thrown if the result still doesn't match the condition after timeout
053: * milliseconds have elapsed
054: */
055: public void waitUntilWithTimeout(Object result, long timeout)
056: throws TimeoutException {
057: _waitUntilWithTimeout(result, timeout);
058: }
059:
060: /**
061: * Waits until the condition matches the expected result. Returns immediately if they match, otherwise waits
062: * for timeout milliseconds or until the results match. This method doesn't throw a TimeoutException
063: * @param result The result, needs to match the condition (using equals()).
064: * @param timeout Number of milliseconds to wait. A value of <= 0 means to wait forever
065: */
066: public void waitUntil(Object result, long timeout) {
067: try {
068: _waitUntilWithTimeout(result, timeout);
069: } catch (TimeoutException e) {
070:
071: }
072: }
073:
074: public void waitUntil(Object result) {
075: try {
076: waitUntilWithTimeout(result, 0);
077: } catch (TimeoutException e) {
078: }
079: }
080:
081: private void _waitUntilWithTimeout(Object result, long timeout)
082: throws TimeoutException {
083: long time_to_wait = timeout, start;
084: boolean timeout_occurred = false;
085: synchronized (lock) {
086: if (result == null && cond == null)
087: return;
088:
089: start = System.currentTimeMillis();
090: while (match(result, cond) == false) {
091: if (timeout <= 0) {
092: doWait();
093: } else {
094: if (time_to_wait <= 0) {
095: timeout_occurred = true;
096: break; // terminate the while loop
097: } else {
098: doWait(time_to_wait);
099: time_to_wait = timeout
100: - (System.currentTimeMillis() - start);
101: }
102: }
103: }
104: if (timeout_occurred)
105: throw new TimeoutException();
106: }
107: }
108:
109: void doWait() {
110: try {
111: lock.wait();
112: } catch (InterruptedException e) {
113: }
114: }
115:
116: void doWait(long timeout) {
117: try {
118: lock.wait(timeout);
119: } catch (InterruptedException e) {
120: }
121: }
122:
123: private boolean match(Object o1, Object o2) {
124: if (o1 != null)
125: return o1.equals(o2);
126: else
127: return o2.equals(o1);
128: }
129:
130: public String toString() {
131: return name + "=" + cond;
132: }
133: }
|