001: /*
002: File: ConditionVariable.java
003: Originally written by Doug Lea and released into the public domain.
004: This may be used for any purposes whatsoever without acknowledgment.
005: Thanks for the assistance and support of Sun Microsystems Labs,
006: and everyone contributing, testing, and using this code.
007: History:
008: Date Who What
009: 11Jun1998 dl Create public version
010: */
011:
012: package org.apache.beehive.netui.util.internal.concurrent;
013:
014: import java.util.*;
015:
016: class CondVar implements Condition, java.io.Serializable {
017:
018: /** The lock **/
019: protected final LockInfo lock;
020:
021: /**
022: * Create a new CondVar that relies on the given mutual
023: * exclusion lock.
024: * @param lock A non-reentrant mutual exclusion lock.
025: **/
026:
027: CondVar(LockInfo lock) {
028: this .lock = lock;
029: }
030:
031: public void awaitUninterruptibly() {
032: boolean wasInterrupted = false;
033: while (true) {
034: try {
035: await();
036: if (wasInterrupted) {
037: Thread.currentThread().interrupt();
038: }
039: return;
040: } catch (InterruptedException e) {
041: wasInterrupted = true;
042: }
043: }
044: }
045:
046: public void await() throws InterruptedException {
047: if (Thread.interrupted())
048: throw new InterruptedException();
049: try {
050: synchronized (this ) {
051: lock.unlock();
052: try {
053: wait();
054: } catch (InterruptedException ex) {
055: notify();
056: throw ex;
057: }
058: }
059: } finally {
060: lock.lock();
061: }
062: }
063:
064: public boolean await(long timeout, TimeUnit unit)
065: throws InterruptedException {
066: if (Thread.interrupted())
067: throw new InterruptedException();
068: long nanos = unit.toNanos(timeout);
069: boolean success = false;
070: try {
071: synchronized (this ) {
072: lock.unlock();
073: try {
074: if (nanos > 0) {
075: long start = Utils.nanoTime();
076: TimeUnit.NANOSECONDS.timedWait(this , nanos);
077: // DK: due to coarse-grained (millis) clock, it seems
078: // preferable to acknowledge timeout (success == false)
079: // when the equality holds (timing is exact)
080: success = Utils.nanoTime() - start < nanos;
081: }
082: } catch (InterruptedException ex) {
083: notify();
084: throw ex;
085: }
086: }
087: } finally {
088: lock.lock();
089: }
090: return success;
091: }
092:
093: // public long awaitNanos(long timeout) throws InterruptedException {
094: // throw new UnsupportedOperationException();
095: // }
096: //
097: public boolean awaitUntil(Date deadline)
098: throws InterruptedException {
099: if (deadline == null)
100: throw new NullPointerException();
101: long abstime = deadline.getTime();
102: if (Thread.interrupted())
103: throw new InterruptedException();
104:
105: boolean success = false;
106: try {
107: synchronized (this ) {
108: lock.unlock();
109: try {
110: long start = System.currentTimeMillis();
111: long msecs = abstime - start;
112: if (msecs > 0) {
113: wait(msecs);
114: // DK: due to coarse-grained (millis) clock, it seems
115: // preferable to acknowledge timeout (success == false)
116: // when the equality holds (timing is exact)
117: success = System.currentTimeMillis() - start < msecs;
118: }
119: } catch (InterruptedException ex) {
120: notify();
121: throw ex;
122: }
123: }
124: } finally {
125: lock.lock();
126: }
127: return success;
128: }
129:
130: public synchronized void signal() {
131: if (!lock.isHeldByCurrentThread()) {
132: throw new IllegalMonitorStateException();
133: }
134: notify();
135: }
136:
137: public synchronized void signalAll() {
138: if (!lock.isHeldByCurrentThread()) {
139: throw new IllegalMonitorStateException();
140: }
141: notifyAll();
142: }
143:
144: static interface LockInfo extends Lock {
145: boolean isHeldByCurrentThread();
146: }
147: }
|