blob: ed22b8aa3ace5974e68159fa9e79bc812513f244 [file] [log] [blame]
/*
* 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.
*/
#ifndef _DECAF_UTIL_TIMER_H_
#define _DECAF_UTIL_TIMER_H_
#include <memory>
#include <decaf/util/Config.h>
#include <decaf/util/Date.h>
#include <decaf/util/concurrent/TimeUnit.h>
#include <decaf/lang/Pointer.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/IllegalStateException.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
namespace decaf {
namespace util {
class TimerTask;
class TimerImpl;
/**
* A facility for threads to schedule tasks for future execution in a background thread.
* Tasks may be scheduled for one-time execution, or for repeated execution at regular
* intervals.
*
* Corresponding to each Timer object is a single background thread that is used to execute
* all of the timer's tasks, sequentially. Timer tasks should complete quickly. If a timer
* task takes excessive time to complete, it "hogs" the timer's task execution thread. This
* can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute
* in rapid succession when (and if) the offending task finally completes.
*
* This class is thread-safe: multiple threads can share a single Timer object without the
* need for external synchronization.
*
* This class does not offer real-time guarantees: it schedules tasks using the wait(long)
* method.
*
* @since 1.0
*/
class DECAF_API Timer {
private:
TimerImpl* internal;
private:
Timer(const Timer&);
Timer operator=(const Timer&);
public:
Timer();
/**
* Create a new Timer whose associated thread is assigned the name given.
*
* @param name
* The name to assign to this Timer's Thread.
*/
Timer(const std::string& name);
virtual ~Timer();
/**
* Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a
* currently executing task (if it exists). Once a timer has been terminated, its execution thread
* terminates gracefully, and no more tasks may be scheduled on it.
*
* Note that calling this method from within the run method of a timer task that was invoked by this
* timer absolutely guarantees that the ongoing task execution is the last task execution that will ever
* be performed by this timer.
*
* This method may be called repeatedly; the second and subsequent calls have no effect.
*/
void cancel();
/**
* The caller will block until the Timer has completed termination meaning all tasks
* that where scheduled before cancelation have now completed and the executor is ready for
* deletion. If the timeout period elapses before the Timer reaches the terminated
* state then this method return false to indicate it has not terminated.
*
* @param timeout
* The amount of time to wait before abandoning the wait for termination.
* @param unit
* The unit of time that the timeout value represents.
*
* @return true if the Timer terminated or false if the timeout expired.
*
* @throws InterruptedException if this call is interrupted while awaiting termination.
*/
bool awaitTermination(long long timeout, const decaf::util::concurrent::TimeUnit& unit);
/**
* Removes all canceled tasks from this timer's task queue. Calling this method has no effect on the
* behavior of the timer, but eliminates the canceled tasks from the queue causing the Timer to destroy
* the TimerTask pointer it was originally given, the caller should ensure that they no longer have
* any references to TimerTasks that were previously scheduled.
*
* Most programs will have no need to call this method. It is designed for use by the rare application
* that cancels a large number of tasks. Calling this method trades time for space: the runtime of the
* method may be proportional to n + c log n, where n is the number of tasks in the queue and c is the
* number of canceled tasks.
*
* This method can be called on a Timer object that has no scheduled tasks without error.
*
* @return the number of tasks removed from the queue.
*/
int purge();
/**
* Schedules the specified task for execution after the specified delay.
*
* The TimerTask pointer is considered to be owned by the Timer class once it has been scheduled, the
* Timer will destroy its TimerTask's once they have been canceled or the Timer itself is canceled.
* A TimerTask is considered scheduled only when this method return without throwing an exception, until
* that time ownership is not considered to have been transferred to the Timer and the caller should
* ensure that the TimerTask gets deleted if an exception is thrown and no further attempts to schedule
* that TimerTask instance are planned.
*
* @param task - task to be scheduled.
* @param delay - delay in milliseconds before task is to be executed.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, or timer was canceled.
*/
void schedule(TimerTask* task, long long delay);
/**
* Schedules the specified task for execution after the specified delay.
*
* @param task - task to be scheduled.
* @param delay - delay in milliseconds before task is to be executed.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, or timer was canceled.
*/
void schedule(const decaf::lang::Pointer<TimerTask>& task, long long delay);
/**
* Schedules the specified task for execution at the specified time. If the time is in the past, the
* task is scheduled for immediate execution.
*
* The TimerTask pointer is considered to be owned by the Timer class once it has been scheduled, the
* Timer will destroy its TimerTask's once they have been canceled or the Timer itself is canceled.
* A TimerTask is considered scheduled only when this method return without throwing an exception, until
* that time ownership is not considered to have been transferred to the Timer and the caller should
* ensure that the TimerTask gets deleted if an exception is thrown and no further attempts to schedule
* that TimerTask instance are planned.
*
* @param task - task to be scheduled.
* @param time - time at which task is to be executed.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if time.getTime() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void schedule(TimerTask* task, const Date& time);
/**
* Schedules the specified task for execution at the specified time. If the time is in the past, the
* task is scheduled for immediate execution.
*
* @param task - task to be scheduled.
* @param time - time at which task is to be executed.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if time.getTime() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void schedule(const decaf::lang::Pointer<TimerTask>& task, const Date& time);
/**
* Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.
* Subsequent executions take place at approximately regular intervals separated by the specified period.
*
* The TimerTask pointer is considered to be owned by the Timer class once it has been scheduled, the
* Timer will destroy its TimerTask's once they have been canceled or the Timer itself is canceled.
* A TimerTask is considered scheduled only when this method return without throwing an exception, until
* that time ownership is not considered to have been transferred to the Timer and the caller should
* ensure that the TimerTask gets deleted if an exception is thrown and no further attempts to schedule
* that TimerTask instance are planned.
*
* In fixed-delay execution, each execution is scheduled relative to the actual execution time of the
* previous execution. If an execution is delayed for any reason (such as other background activity),
* subsequent executions will be delayed as well. In the long run, the frequency of execution will
* generally be slightly lower than the reciprocal of the specified period (assuming the system clock
* underlying Object.wait(long long) is accurate).
*
* Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other
* words, it is appropriate for activities where it is more important to keep the frequency accurate
* in the short run than in the long run. This includes most animation tasks, such as blinking a cursor
* at regular intervals. It also includes tasks wherein regular activity is performed in response to
* human input, such as automatically repeating a character as long as a key is held down.
*
* @param task - task to be scheduled.
* @param delay - delay in milliseconds before task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void schedule(TimerTask* task, long long delay, long long period);
/**
* Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.
* Subsequent executions take place at approximately regular intervals separated by the specified period.
*
* In fixed-delay execution, each execution is scheduled relative to the actual execution time of the
* previous execution. If an execution is delayed for any reason (such as other background activity),
* subsequent executions will be delayed as well. In the long run, the frequency of execution will
* generally be slightly lower than the reciprocal of the specified period (assuming the system clock
* underlying Object.wait(long long) is accurate).
*
* Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other
* words, it is appropriate for activities where it is more important to keep the frequency accurate
* in the short run than in the long run. This includes most animation tasks, such as blinking a cursor
* at regular intervals. It also includes tasks wherein regular activity is performed in response to
* human input, such as automatically repeating a character as long as a key is held down.
*
* @param task - task to be scheduled.
* @param delay - delay in milliseconds before task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void schedule(const decaf::lang::Pointer<TimerTask>& task, long long delay, long long period);
/**
* Schedules the specified task for repeated fixed-delay execution, beginning at the specified time.
* Subsequent executions take place at approximately regular intervals separated by the specified period.
*
* The TimerTask pointer is considered to be owned by the Timer class once it has been scheduled, the
* Timer will destroy its TimerTask's once they have been canceled or the Timer itself is canceled.
* A TimerTask is considered scheduled only when this method return without throwing an exception, until
* that time ownership is not considered to have been transferred to the Timer and the caller should
* ensure that the TimerTask gets deleted if an exception is thrown and no further attempts to schedule
* that TimerTask instance are planned.
*
* In fixed-delay execution, each execution is scheduled relative to the actual execution time of the
* previous execution. If an execution is delayed for any reason (such as other background activity),
* subsequent executions will be delayed as well. In the long run, the frequency of execution will
* generally be slightly lower than the reciprocal of the specified period (assuming the system clock
* underlying Object.wait(long long) is accurate).
*
* Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other
* words, it is appropriate for activities where it is more important to keep the frequency accurate
* in the short run than in the long run. This includes most animation tasks, such as blinking a cursor
* at regular intervals. It also includes tasks wherein regular activity is performed in response to
* human input, such as automatically repeating a character as long as a key is held down.
*
* @param task - task to be scheduled.
* @param firstTime - First time at which task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if time.getTime() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void schedule(TimerTask* task, const Date& firstTime, long long period);
/**
* Schedules the specified task for repeated fixed-delay execution, beginning at the specified time.
* Subsequent executions take place at approximately regular intervals separated by the specified period.
*
* In fixed-delay execution, each execution is scheduled relative to the actual execution time of the
* previous execution. If an execution is delayed for any reason (such as other background activity),
* subsequent executions will be delayed as well. In the long run, the frequency of execution will
* generally be slightly lower than the reciprocal of the specified period (assuming the system clock
* underlying Object.wait(long long) is accurate).
*
* Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other
* words, it is appropriate for activities where it is more important to keep the frequency accurate
* in the short run than in the long run. This includes most animation tasks, such as blinking a cursor
* at regular intervals. It also includes tasks wherein regular activity is performed in response to
* human input, such as automatically repeating a character as long as a key is held down.
*
* @param task - task to be scheduled.
* @param firstTime - First time at which task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if time.getTime() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void schedule(const decaf::lang::Pointer<TimerTask>& task, const Date& firstTime, long long period);
/**
* Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.
* Subsequent executions take place at approximately regular intervals, separated by the specified period.
*
* The TimerTask pointer is considered to be owned by the Timer class once it has been scheduled, the
* Timer will destroy its TimerTask's once they have been canceled or the Timer itself is canceled.
* A TimerTask is considered scheduled only when this method return without throwing an exception, until
* that time ownership is not considered to have been transferred to the Timer and the caller should
* ensure that the TimerTask gets deleted if an exception is thrown and no further attempts to schedule
* that TimerTask instance are planned.
*
* In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the
* initial execution. If an execution is delayed for any reason (such as garbage collection or other
* background activity), two or more executions will occur in rapid succession to "catch up." In the
* long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming
* the system clock underlying Object.wait(long) is accurate).
*
* Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such
* as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular
* time. It is also appropriate for recurring activities where the total time to perform a fixed number
* of executions is important, such as a count down timer that ticks once every second for ten seconds.
* Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must
* remain synchronized with respect to one another.
*
* @param task - task to be scheduled.
* @param delay - delay in milliseconds before task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void scheduleAtFixedRate(TimerTask* task, long long delay, long long period);
/**
* Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.
* Subsequent executions take place at approximately regular intervals, separated by the specified period.
*
* In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the
* initial execution. If an execution is delayed for any reason (such as garbage collection or other
* background activity), two or more executions will occur in rapid succession to "catch up." In the
* long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming
* the system clock underlying Object.wait(long) is accurate).
*
* Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such
* as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular
* time. It is also appropriate for recurring activities where the total time to perform a fixed number
* of executions is important, such as a countdown timer that ticks once every second for ten seconds.
* Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must
* remain synchronized with respect to one another.
*
* @param task - task to be scheduled.
* @param delay - delay in milliseconds before task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void scheduleAtFixedRate(const decaf::lang::Pointer<TimerTask>& task, long long delay, long long period);
/**
* Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.
* Subsequent executions take place at approximately regular intervals, separated by the specified period.
*
* The TimerTask pointer is considered to be owned by the Timer class once it has been scheduled, the
* Timer will destroy its TimerTask's once they have been canceled or the Timer itself is canceled.
* A TimerTask is considered scheduled only when this method return without throwing an exception, until
* that time ownership is not considered to have been transferred to the Timer and the caller should
* ensure that the TimerTask gets deleted if an exception is thrown and no further attempts to schedule
* that TimerTask instance are planned.
*
* In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the
* initial execution. If an execution is delayed for any reason (such as garbage collection or other
* background activity), two or more executions will occur in rapid succession to "catch up." In the
* long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming
* the system clock underlying Object.wait(long) is accurate).
*
* Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such
* as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular
* time. It is also appropriate for recurring activities where the total time to perform a fixed number
* of executions is important, such as a countdown timer that ticks once every second for ten seconds.
* Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must
* remain synchronized with respect to one another.
*
* @param task - task to be scheduled.
* @param firstTime - First time at which task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if time.getTime() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void scheduleAtFixedRate(TimerTask* task, const Date& firstTime, long long period);
/**
* Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.
* Subsequent executions take place at approximately regular intervals, separated by the specified period.
*
* In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the
* initial execution. If an execution is delayed for any reason (such as garbage collection or other
* background activity), two or more executions will occur in rapid succession to "catch up." In the
* long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming
* the system clock underlying Object.wait(long) is accurate).
*
* Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such
* as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular
* time. It is also appropriate for recurring activities where the total time to perform a fixed number
* of executions is important, such as a countdown timer that ticks once every second for ten seconds.
* Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must
* remain synchronized with respect to one another.
*
* @param task - task to be scheduled.
* @param firstTime - First time at which task is to be executed.
* @param period - time in milliseconds between successive task executions.
*
* @throw NullPointerException - if the TimerTask value is Null.
* @throw IllegalArgumentException - if time.getTime() is negative.
* @throw IllegalStateException - if task was already scheduled or canceled, timer was canceled, or
* timer thread terminated.
*/
void scheduleAtFixedRate(const decaf::lang::Pointer<TimerTask>& task, const Date& firstTime, long long period);
private:
void scheduleTask(const decaf::lang::Pointer<TimerTask>& task, long long delay, long long period, bool fixed);
};
}}
#endif /* _DECAF_UTIL_TIMER_H_ */