/* * Copyright 2007-2010 Sun Microsystems, Inc. * * This file is part of Project Darkstar Server. * * Project Darkstar Server is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation and * distributed hereunder to you. * * Project Darkstar Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * -- */ package com.sun.sgs.impl.kernel.schedule; import com.sun.sgs.kernel.schedule.ScheduledTask; import com.sun.sgs.kernel.schedule.SchedulerQueue; import com.sun.sgs.kernel.RecurringTaskHandle; import java.util.TimerTask; /** * Simple implementation of <code>RecurringTaskHandle</code> that lets * the handle be associated with a <code>TimerTask</code> so that cancelling * the handle also cancels the associated <code>TimerTask</code>. */ class RecurringTaskHandleImpl implements RecurringTaskHandle { // the queue using this handle private final SchedulerQueue queue; // the actual task to run private ScheduledTask task; // the associated timer task private TimerTask currentTimerTask = null; // whether or not this task has been cancelled; synchronize on this // handle before using this field private boolean cancelled = false; // whether or not this task has been started private boolean started = false; /** * Creates an instance of <code>RecurringTaskHandleImpl</code>. * * @param queue the <code>SchedulerQueue</code> that is using * this handle * @param task the task for this handle * * @throws IllegalArgumentException if the task is not recurring */ public RecurringTaskHandleImpl(SchedulerQueue queue, ScheduledTask task) { if (queue == null) { throw new NullPointerException("Queue cannot be null"); } if (task == null) { throw new NullPointerException("Task cannot be null"); } if (!task.isRecurring()) { throw new IllegalArgumentException("Task must be recurring"); } this.queue = queue; this.task = task; } /** * Sets the associated <code>TimerTask</code> for this handle. This * method may be called any number of times on a handle. Typically * a recurring task will re-set the associated <code>TimerTask</code> * with each recurrence of execution. * * @param timerTask the associated <code>TimerTask</code> */ synchronized void setTimerTask(TimerTask timerTask) { if (timerTask == null) { throw new NullPointerException("TimerTask cannot be null"); } currentTimerTask = timerTask; } /** * Returns whether this handle has been cancelled. This does not say * anything about the state of any associated <code>TimerTask</code>. * * @return <code>true</code> if this handle has been cancelled, * <code>false</code> otherwise */ synchronized boolean isCancelled() { return cancelled; } /** * Cancels this handle, which will also cancel the associated * <code>TimerTask</code> and notify the <code>SchedulerQueue</code> * about the task being cancelled. If this handle has already been * cancelled, then an exception is thrown. * * @throws IllegalStateException if this handle has already been cancelled */ public void cancel() { synchronized (this) { if (cancelled) { throw new IllegalStateException("cannot cancel task"); } cancelled = true; } try { if (task.cancel(false)) { queue.notifyCancelled(task); } } catch (InterruptedException ie) { // this will never happen because false was passed to cancel() } if (currentTimerTask != null) { currentTimerTask.cancel(); } } /** * Starts the associated task running by passing the task to the * <code>SchedulerQueue</code> via a call to <code>addTask</code>. * If this handle has already been started or cancelled, then an * exception is thrown. * * @throws IllegalStateException if the handle has already been started * or cancelled */ public void start() { synchronized (this) { if ((cancelled) || (started)) { throw new IllegalStateException("cannot start task"); } started = true; } queue.addTask(task); } }