summaryrefslogtreecommitdiffstats
path: root/core/java/android/os/ConditionVariable.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/os/ConditionVariable.java')
-rw-r--r--core/java/android/os/ConditionVariable.java141
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;
+ }
+ }
+}