/*
* 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.app.TaskRejectedException;
import com.sun.sgs.impl.sharedutil.LoggerWrapper;
import com.sun.sgs.kernel.RecurringTaskHandle;
import com.sun.sgs.kernel.TaskReservation;
import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This is a simple implemenation of <code>SchedulerQueue</code> that
* accepts tasks and runs them in the order that they are ready. No attempt
* is made to support priority, or to provide any degree of fairness
* between users. This class uses an un-bounded queue. Unless the system
* runs out of memory, this should always accept any tasks from any user.
*/
public class FIFOSchedulerQueue implements SchedulerQueue, TimedTaskListener {
// logger for this class
private static final LoggerWrapper logger =
new LoggerWrapper(Logger.getLogger(FIFOSchedulerQueue.
class.getName()));
// the single queue of tasks
private LinkedBlockingQueue<ScheduledTask> queue;
// the handler for all delayed tasks
private final TimedTaskHandler timedTaskHandler;
/**
* Creates an instance of <code>FIFOSchedulerQueue</code>.
*
* @param properties the available system properties
*/
public FIFOSchedulerQueue(Properties properties) {
logger.log(Level.CONFIG, "Creating a FIFO Scheduler Queue");
if (properties == null) {
throw new NullPointerException("Properties cannot be null");
}
queue = new LinkedBlockingQueue<ScheduledTask>();
timedTaskHandler = new TimedTaskHandler(this);
}
/**
* {@inheritDoc}
*/
public int getReadyCount() {
return queue.size();
}
/**
* {@inheritDoc}
*/
public ScheduledTask getNextTask(boolean wait)
throws InterruptedException
{
ScheduledTask task = queue.poll();
if ((task != null) || (!wait)) {
return task;
}
return queue.take();
}
/**
* {@inheritDoc}
*/
public int getNextTasks(Collection<? super ScheduledTask> tasks, int max) {
return queue.drainTo(tasks, max);
}
/**
* {@inheritDoc}
*/
public TaskReservation reserveTask(ScheduledTask task) {
if (task.isRecurring()) {
throw new TaskRejectedException("Recurring tasks cannot get " +
"reservations");
}
return new SimpleTaskReservation(this, task);
}
/**
* {@inheritDoc}
*/
public void addTask(ScheduledTask task) {
if (task == null) {
throw new NullPointerException("Task cannot be null");
}
if (!timedTaskHandler.runDelayed(task)) {
// check if the task is recurring, because we're not allowed to
// reject those tasks
if (!task.isRecurring()) {
if (!queue.offer(task)) {
throw new TaskRejectedException("Request was rejected");
}
} else {
timedTaskReady(task);
}
}
}
/**
* {@inheritDoc}
*/
public RecurringTaskHandle createRecurringTaskHandle(ScheduledTask task) {
if (task == null) {
throw new NullPointerException("Task cannot be null");
}
if (!task.isRecurring()) {
throw new IllegalArgumentException("Not a recurring task");
}
return new RecurringTaskHandleImpl(this, task);
}
/**
* {@inheritDoc}
*/
public void notifyCancelled(ScheduledTask task) {
// FIXME: do we want to pull the task out of the queue?
}
/**
* {@inheritDoc}
*/
public void timedTaskReady(ScheduledTask task) {
boolean success;
do {
success = queue.offer(task);
} while(!success);
}
/**
* {@inheritDoc}
*/
public void shutdown() {
timedTaskHandler.shutdown();
}
}