5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster/**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * The contents of this file are subject to the terms
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * of the Common Development and Distribution License
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * (the License). You may not use this file except in
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * compliance with the License.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * You can obtain a copy of the License at
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * opensso/legal/CDDLv1.0.txt
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * See the License for the specific language governing
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * permission and limitations under the License.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * When distributing Covered Code, include this CDDL
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Header Notice in each file and include the License file
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * at opensso/legal/CDDLv1.0.txt.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * If applicable, add the following below the CDDL Header,
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * with the fields enclosed by brackets [] replaced by
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * your own identifying information:
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * $Id: HeadTaskRunnable.java,v 1.4 2008/06/25 05:52:51 qcheng Exp $
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Fosterpackage com.sun.identity.common;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Fosterimport java.util.Date;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Fosterimport java.util.Set;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster/**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * HeadTaskRunnable is designed to be the head of the linked-list when
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * TaskRunnable needs to be linked together. Whenever there is an insertion or
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * deletion, HeadTaskRunnable must be locked to guarantee correct
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * synchronization. Besides, when last element of the linked-list is removed
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * (setNext(null)), HeadTaskRunnable should use Triggerable to remove or destroy
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * the linked-list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Fosterpublic class HeadTaskRunnable implements TaskRunnable {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected Date time;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected volatile TaskRunnable nextTask;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected volatile TaskRunnable tailTask;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected volatile boolean expired;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected volatile boolean timeout;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected int waitCount;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected int acquireCount;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected volatile Thread owner;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected Triggerable parent;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Constructor of HeadTaskRunnable.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @param parent The Triggerable interface to be run when the linked-list is
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * empty
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @param nextTask The TaskRunnable next to this TaskRunnable
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @param time The time this TaskRunnable is scheduled
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public HeadTaskRunnable(Triggerable parent, TaskRunnable nextTask,
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster Date time) throws IllegalArgumentException {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if ((time == null) || (nextTask == null)) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster throw new IllegalArgumentException();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.time = time;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.owner = null;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.nextTask = nextTask;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.tailTask = nextTask;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.expired = false;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.timeout = false;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.waitCount = 0;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.acquireCount = 0;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.nextTask.setHeadTask(this);
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.nextTask.setPrevious(this);
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.parent = parent;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Sets the status of the HeadTask to expired.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected synchronized void expire() throws IllegalMonitorStateException {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (owner == Thread.currentThread()) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster expired = true;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster throw new IllegalMonitorStateException(
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster "The calling thread is not the owner of the lock!");
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Sets the status of the HeadTask to timeout.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster protected synchronized void timeout() throws IllegalMonitorStateException {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (owner == Thread.currentThread()) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster timeout = true;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster throw new IllegalMonitorStateException(
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster "The calling thread is not the owner of the lock!");
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Returns a boolean to indicate whether the HeadTask is timeout already.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return a boolen to indicate whether the HeadTask is timeout.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public boolean isTimedOut() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return timeout;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Returns a boolean to indicate whether the HeadTask is expired already.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return a boolean to indicate whether the HeadTask is expired.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public boolean isExpired() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return expired;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Returns the thread which currently holding this lock.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return the thread which currently own the lock or null.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public Thread getCurrentOwner() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return owner;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Tries to acquire a valid (non-expired) lock.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return a boolean to indicate whether it is succeed to acquire the lock.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public synchronized boolean acquireValidLock() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster while (!expired) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (owner == null) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster owner = Thread.currentThread();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster acquireCount = 1;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return true;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (owner != Thread.currentThread()) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster try {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster waitCount++;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.wait();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster waitCount--;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } catch (InterruptedException ex){
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster //ignored
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster acquireCount++;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return true;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return false;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Releases the currently holding lock.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public synchronized void releaseLockAndNotify() throws
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster IllegalMonitorStateException {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (owner == Thread.currentThread()) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (acquireCount > 1) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster acquireCount--;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster owner = null;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster acquireCount = 0;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (waitCount > 0) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (expired) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.notifyAll();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.notify();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster throw new IllegalMonitorStateException(
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster "The calling thread is not the owner of the lock!");
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, no actual use for HeadTaskRunnable.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void setHeadTask(HeadTaskRunnable headTask) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, no actual use for HeadTaskRunnable.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public HeadTaskRunnable getHeadTask() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return null;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, always return false.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return false means nothing can be added to this TaskRunnable
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public boolean addElement(Object key) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return false;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, always return false.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return false means nothing can be removed from this TaskRunnable
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public boolean removeElement(Object key) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return false;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, always return false.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return true means this TaskRunnable is always empty
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public boolean isEmpty() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return true;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Sets the TaskRunnable next to this TaskRunnable in the linked-list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @param task The next TaskRunnable
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void setNext(TaskRunnable task) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (task == null) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster synchronized (this) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (parent != null) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster parent.trigger(time);
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster nextTask = null;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster nextTask = task;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, There is no previous element for
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * HeadTaskRunnable.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void setPrevious(TaskRunnable task) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Returns the TaskRunnable next to this TaskRunnable in the linked-list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return next TaskRunnable object or null if it is not set
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public TaskRunnable next() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return nextTask;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, there is no previous element for
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * HeadTaskRunnable.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return null means there is no previous element
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public TaskRunnable previous() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return null;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, HeadTaskRunnable doesn't have a
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * run period.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return -1 means the task only will be run once
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public long getRunPeriod() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return -1;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void cancel() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (acquireValidLock()) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster try {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster synchronized (this) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (parent != null) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster parent.trigger(time);
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } finally {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster releaseLockAndNotify();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Sets the Triggerable interface which will be run when the linked-list is
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * empty.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @param parent The Triggerable interface to be run when the linked-list is
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * empty
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void setTrigger(Triggerable parent) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster synchronized (this) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster this.parent = parent;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Sets the task which is the tail of the list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * It is for internal use only.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @param task The task which is at the tail of the list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void setTail(TaskRunnable task) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster tailTask = task;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Returns the Task which is at the tail of the list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return The task which is at the tail of the list.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public TaskRunnable tail() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return tailTask;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Returns the time which this HeadTaskRunnable is scheduled.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster *
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * @return The long value which represents the time this task is scheduled
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public long scheduledExecutionTime() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster if (expired) {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return -1;
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } else {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster return time.getTime();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster /**
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster * Implements for TaskRunnable interface, just run the next TaskRunnable.
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster */
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster public void run() {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster TaskRunnable taskToRun = next();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster do {
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster taskToRun.run();
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster } while ((taskToRun = taskToRun.next()) != null);
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster }
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster
5c099afa7c9361afc2f4477fec0e3018588d7840Allan Foster}