/*
 * 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 as 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 maximum 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;
        }
    }
}
