/*
 * 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.tribes.transport.bio.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 ) {
                    Thread.currentThread().interrupted();
                }
            } 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 ) {
                    Thread.currentThread().interrupted();
                }
            } 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();
        }
    }

}
