/* * 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. * *
* 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. * *
* 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. * *
* Pass true for opened and false for closed. */ public ConditionVariable(boolean state) { mCondition = state; } /** * Open the condition, and release all threads that are blocked. * *
* 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. * *
* 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. * *
* 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. * *
* 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; } } }