/* * Copyright (C) 2012 Red Hat, Inc. and/or its affiliates. * * Licensed 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.jboss.errai.bus.server.async; import static java.lang.System.currentTimeMillis; import org.jboss.errai.common.client.api.tasks.AsyncTask; /** * A <tt>TimedTask</tt> is used for scheduling tasks, and making sure they are run at appropriate times and intervals */ public abstract class TimedTask implements Runnable, Comparable<TimedTask>, AsyncTask { protected volatile long nextRuntime; protected volatile long period; protected volatile boolean cancelled = false; protected volatile InterruptHandle interruptHook; protected volatile Runnable exitHandler; /** * Gets the period of the task, and when it should be run next * * @return the interval length */ public long getPeriod() { return period; } /** * Sets the period in which the task should be run next * * @param period */ public void setPeriod(long period) { this.period = period; } public void cancel() { period = -1; } /** * Gets the time in which the task will be run. If -1 is returned, the task is permanently de-scheduled. * * @return the time the task will be run in milliseconds */ public long nextRuntime() { return nextRuntime; } @Override public void cancel(boolean interrupt) { if (interrupt && interruptHook != null) interruptHook.sendInterrupt(); cancelled = true; } /** * Returns true if the task has been cancelled or is expired. * * @return */ @Override public boolean isCancelled() { return cancelled; } public boolean calculateNextRuntime() { synchronized (this) { if (!cancelled && period != -1) { nextRuntime = currentTimeMillis() + period; return true; } else { nextRuntime = -1; return false; } } } public boolean isDue(long time) { synchronized (this) { return !cancelled && nextRuntime <= time && nextRuntime != -1; } } @Override public void setExitHandler(Runnable runnable) { if (exitHandler != null) { throw new IllegalStateException("Exit handler already set to " + exitHandler); } this.exitHandler = runnable; if (!isDue(currentTimeMillis())) { runnable.run(); } } @Override public int compareTo(TimedTask o) { if (o == this) { return 0; } if (nextRuntime > o.nextRuntime) return 1; else if (nextRuntime < o.nextRuntime) return -1; else return 0; } }