diff options
Diffstat (limited to 'core/java/android/os/ConditionVariable.java')
-rw-r--r-- | core/java/android/os/ConditionVariable.java | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/core/java/android/os/ConditionVariable.java b/core/java/android/os/ConditionVariable.java new file mode 100644 index 0000000..95a9259 --- /dev/null +++ b/core/java/android/os/ConditionVariable.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +/** + * Class that implements the condition variable locking paradigm. + * + * <p> + * This differs from the built-in java.lang.Object wait() and notify() + * in that this class contains the condition to wait on itself. That means + * open(), close() and block() are sticky. If open() is called before block(), + * block() will not block, and instead return immediately. + * + * <p> + * This class uses itself is at the object to wait on, so if you wait() + * or notify() on a ConditionVariable, the results are undefined. + */ +public class ConditionVariable +{ + private volatile boolean mCondition; + + /** + * Create the ConditionVariable in the default closed state. + */ + public ConditionVariable() + { + mCondition = false; + } + + /** + * Create the ConditionVariable with the given state. + * + * <p> + * Pass true for opened and false for closed. + */ + public ConditionVariable(boolean state) + { + mCondition = state; + } + + /** + * Open the condition, and release all threads that are blocked. + * + * <p> + * Any threads that later approach block() will not block unless close() + * is called. + */ + public void open() + { + synchronized (this) { + boolean old = mCondition; + mCondition = true; + if (!old) { + this.notifyAll(); + } + } + } + + /** + * Reset the condition to the closed state. + * + * <p> + * Any threads that call block() will block until someone calls open. + */ + public void close() + { + synchronized (this) { + mCondition = false; + } + } + + /** + * Block the current thread until the condition is opened. + * + * <p> + * If the condition is already opened, return immediately. + */ + public void block() + { + synchronized (this) { + while (!mCondition) { + try { + this.wait(); + } + catch (InterruptedException e) { + } + } + } + } + + /** + * Block the current thread until the condition is opened or until + * timeout milliseconds have passed. + * + * <p> + * If the condition is already opened, return immediately. + * + * @param timeout the minimum time to wait in milliseconds. + * + * @return true if the condition was opened, false if the call returns + * because of the timeout. + */ + public boolean block(long timeout) + { + // Object.wait(0) means wait forever, to mimic this, we just + // call the other block() method in that case. It simplifies + // this code for the common case. + if (timeout != 0) { + synchronized (this) { + long now = System.currentTimeMillis(); + long end = now + timeout; + while (!mCondition && now < end) { + try { + this.wait(end-now); + } + catch (InterruptedException e) { + } + now = System.currentTimeMillis(); + } + return mCondition; + } + } else { + this.block(); + return true; + } + } +} |