/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.catalina.cluster.util;

/**
 * The class <b>SingleRemoveSynchronizedAddLock</b> implement locking for accessing the queue
 * by a single remove thread and multiple add threads.
 *
 * A thread is only allowed to be either the remove or
 * an add thread.
 *
 * The lock can either be owned by the remove thread
 * or by a single add thread.
 *
 * If the remove thread tries to get the lock,
 * but the queue is empty, it will block (poll)
 * until an add threads adds an entry to the queue and
 * releases the lock.
 * 
 * If the remove thread and add threads compete for
 * the lock and an add thread releases the lock, then
 * the remove thread will get the lock first.
 *
 * The remove thread removes all entries in the queue
 * at once and proceeses them without further
 * polling the queue.
 *
 * The lock is not reentrant, in the sense, that all
 * threads must release an owned lock before competing
 * for the lock again!
 *
 * @author Rainer Jung
 * @author Peter Rossbach
 * @version 1.1
 */
 
public class SingleRemoveSynchronizedAddLock {
    
    public SingleRemoveSynchronizedAddLock() {
    }
    
    public SingleRemoveSynchronizedAddLock(boolean dataAvailable) {
        this.dataAvailable=dataAvailable;
    }
    
    /**
     * Time in milliseconds after which threads
     * waiting for an add lock are woken up.
     * This is used as a safety measure in case
     * thread notification via the unlock methods
     * has a bug.
     */
    private long addWaitTimeout = 10000L;

    /**
     * Time in milliseconds after which threads
     * waiting for a remove lock are woken up.
     * This is used as a safety measure in case
     * thread notification via the unlock methods
     * has a bug.
     */
    private long removeWaitTimeout = 30000L;

    /**
     * The current remove thread.
     * It is set to the remove thread polling for entries.
     * It is reset to null when the remove thread
     * releases the lock and proceeds processing
     * the removed entries.
     */
    private Thread remover = null;

    /**
     * A flag indicating, if an add thread owns the lock.
     */
    private boolean addLocked = false;

    /**
     * A flag indicating, if the remove thread owns the lock.
     */
    private boolean removeLocked = false;

    /**
     * A flag indicating, if the remove thread is allowed
     * to wait for the lock. The flag is set to false, when aborting.
     */
    private boolean removeEnabled = true;

    /**
     * A flag indicating, if the remover needs polling.
     * It indicates, if the locked object has data available
     * to be removed.
     */
    private boolean dataAvailable = false;

    /**
     * @return Value of addWaitTimeout
     */
    public synchronized long getAddWaitTimeout() {
        return addWaitTimeout;
    }

    /**
     * Set value of addWaitTimeout
     */
    public synchronized void setAddWaitTimeout(long timeout) {
        addWaitTimeout = timeout;
    }

    /**
     * @return Value of removeWaitTimeout
     */
    public synchronized long getRemoveWaitTimeout() {
        return removeWaitTimeout;
    }

    /**
     * Set value of removeWaitTimeout
     */
    public synchronized void setRemoveWaitTimeout(long timeout) {
        removeWaitTimeout = timeout;
    }

    /**
     * Check if the locked object has data available
     * i.e. the remover can stop poling and get the lock.
     * @return True iff the lock Object has data available.
     */
    public synchronized boolean isDataAvailable() {
        return dataAvailable;
    }

    /**
     * Check if an add thread owns the lock.
     * @return True iff an add thread owns the lock.
     */
    public synchronized boolean isAddLocked() {
        return addLocked;
    }

    /**
     * Check if the remove thread owns the lock.
     * @return True iff the remove thread owns the lock.
     */
    public synchronized boolean isRemoveLocked() {
        return removeLocked;
    }

    /**
     * Check if the remove thread is polling.
     * @return True iff the remove thread is polling.
     */
    public synchronized boolean isRemovePolling() {
        if ( remover != null ) {
            return true;
        }
        return false;
    }

    /**
     * Acquires the lock by an add thread and sets the add flag.
     * If any add thread or the remove thread already acquired the lock
     * this add thread will block until the lock is released.
     */
    public synchronized void lockAdd() {
        if ( addLocked || removeLocked ) {
            do {
                try {
                    wait(addWaitTimeout);
                } catch ( InterruptedException e ) {
                }
            } while ( addLocked || removeLocked );
        }
        addLocked=true;
    }

    /**
     * Acquires the lock by the remove thread and sets the remove flag.
     * If any add thread already acquired the lock or the queue is
     * empty, the remove thread will block until the lock is released
     * and the queue is not empty.
     */
    public synchronized boolean lockRemove() {
        removeLocked=false;
        removeEnabled=true;
        if ( ( addLocked || ! dataAvailable ) && removeEnabled ) {
            remover=Thread.currentThread();
            do {
                try {
                    wait(removeWaitTimeout);
                } catch ( InterruptedException e ) {
                }
            } while ( ( addLocked || ! dataAvailable ) && removeEnabled );
            remover=null;
        }
        if ( removeEnabled ) {
            removeLocked=true;
        } 
        return removeLocked;
    }

    /**
     * Releases the lock by an add thread and reset the remove flag.
     * If the reader thread is polling, notify it.
     */
    public synchronized void unlockAdd(boolean dataAvailable) {
        addLocked=false;
        this.dataAvailable=dataAvailable;
        if ( ( remover != null ) && ( dataAvailable || ! removeEnabled ) ) {
            remover.interrupt();
        } else {
            notifyAll();
        }
    }

    /**
     * Releases the lock by the remove thread and reset the add flag.
     * Notify all waiting add threads,
     * that the lock has been released by the remove thread.
     */
    public synchronized void unlockRemove() {
        removeLocked=false;
        dataAvailable=false;
        notifyAll();
    }

    /**
     * Abort any polling remover thread
     */
    public synchronized void abortRemove() {
        removeEnabled=false;
        if ( remover != null ) {
            remover.interrupt();
        }
    }

}
