/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: TimerPool.java,v 1.6 2008/10/20 22:00:05 ww203982 Exp $
*
* Portions Copyrighted 2012-2016 ForgeRock AS.
*/
/**
* TimerPool is a scheduleable version of ThreadPool.
*/
private int poolSize;
private int busyThreadCount;
private int currentThreadCount;
private volatile boolean shutdownThePool;
private boolean daemon;
/**
* Constructor of TimerPool.
*
* @param name The name of the TimerPool
* @param poolSize The size of the TimerPool
* @param daemon The boolean to indicate whether the threads in TimerPool
* are daemon
* @param debug Debug object to send debugging message to.
*/
this.busyThreadCount = 0;
this.currentThreadCount = 0;
this.shutdownThePool = false;
synchronized (this) {
}
}
/**
* Creates threads to the TimerPool.
*
* @param timersToCreate Number of threads in the TimerPool after creation
*/
if (timersToCreate > poolSize) {
}
for (int i = currentThreadCount; i < timersToCreate; i++) {
}
}
/**
* Returns thread which is free in the pool.
*
* @return A thread which is free from the TimerPool
*/
WorkerThread t = null;
synchronized (this) {
if (currentThreadCount == busyThreadCount) {
}
}
return t;
}
/**
* Runs the next timeout task in the sorted container.
*/
private void runNext() {
WorkerThread t = null;
synchronized (this) {
if (shutdownThePool) {
return;
} else {
while (busyThreadCount == poolSize) {
try {
wait();
if (shutdownThePool) {
return;
}
}
}
}
long now = currentTimeMillis();
!= null) {
t = getAvailableThread();
}
}
try {
} catch(NoSuchElementException ex) {
}
}
}
}
}
}
/**
* Decreases the number of current threads in the TimerPool.
*/
private synchronized void deductCurrentThreadCount(){
notify();
}
/**
* Replaces the scheduler thread in the TimerPool.
*/
private synchronized void replaceScheduler() {
}
/**
* Returns the thread to the TimerPool.
*
* @param t The thread to be returned to the TimerPool
*/
if (shutdownThePool) {
t.terminate();
synchronized (this) {
if(busyThreadCount == 0){
notifyAll();
}
}
} else {
synchronized (this) {
// return timers from the end of array
notify();
}
}
}
/**
* Schedules a TaskRunnable to the TimerPool.
*
* @param task The TaskRunnable to be scheduled
* @param time The time to run the TaskRunnable
*/
if (shutdownThePool) {
throw new IllegalStateException(
"The timers have been shuted down!");
} else {
do {
if (head.acquireValidLock()) {
try {
if (head.scheduledExecutionTime() ==
return;
} else {
if (!head.isTimedOut()) {
throw new IllegalStateException(
"The task has been scheduled!");
}
}
}
} finally {
}
}
}
synchronized (taskList) {
time));
}
}
synchronized (this) {
}
}
} else {
if (head.acquireValidLock()) {
try {
} finally {
}
} else {
}
}
} else {
throw new IllegalArgumentException();
}
}
}
/**
* Schedules the TaskRunnable to the TimerPool.
*
* @param task The TaskRunnable to be scheduled
* @param delay The time (in ms) to wait before running the task
*/
}
/**
* Implements the trigger function for Triggerable interface.
*/
// no need to synchronize for single operation
}
/**
* Shuts down the TimerPool.
*/
public synchronized void shutdown() {
if(!shutdownThePool) {
shutdownThePool = true;
// terminate the thread from the beginning of the array
}
while(busyThreadCount != 0){
try{
// wait if there are threads running, it will be notified
// when they all back.
wait();
}
}
}
}
}
/**
* WorkerThread is the threads which actually do the jobs. A WorkerThread
* will be assigned to the task when it is time.
*/
private volatile boolean shouldTerminate;
private volatile boolean needReturn;
/**
* Constructor of WorkerThread.
*
* @param name The name of the thread
* @param pool The TimerPool the thread belongs to
*/
this.shouldTerminate = false;
this.needReturn = true;
}
/**
* Runs the task.
*
* @param toRun The head of the tasks to be run
*/
// Although the thread may not in wait state when this function
// is called (the taskList is not empty), it doesn't hurt to
// call it. getState method can check whether the Thread is
// waiting, but it is available in jdk1.5 or newer.
this.notify();
}
/**
* Terminates this WorkerThread.
*/
// terminate the thread pool when daemon is set to false
// it is better to have a way to terminate the thread pool
public synchronized void terminate() {
shouldTerminate = true;
needReturn = false;
this.notify();
}
/**
* Implements the run method with errors handling for Thread object.
*/
public void run() {
WorkerThread t = this;
while (true) {
try{
synchronized(this) {
this.wait();
}
// need a local copy because they may be changed after
// leaving synchronized block.
}
if (shouldTerminate) {
// we may need to log something here!
break;
}
if(localHeadTask != null){
if (localHeadTask.acquireValidLock()) {
try {
// skip head task
// cut the connection before run the task.
+ runTask.getRunPeriod()));
}
}
} finally {
}
}
}
} catch (IllegalStateException ex) {
ex);
}
// This exception will be thrown only if the Timer has been
// shutdown already.
shouldTerminate = true;
} catch (RuntimeException ex) {
}
if (localHeadTask != null) {
if (localHeadTask.acquireValidLock()) {
try {
+ runTask.getRunPeriod()));
}
}
} catch (IllegalStateException iex) {
}
// This exception will be thrown only if the
// Timer has been shutdown already.
shouldTerminate = true;
} finally {
}
}
}
synchronized (pool) {
}
}
shouldTerminate = true;
needReturn = false;
}
// don't need to rethrow
} catch (Throwable e) {
}
if (localHeadTask != null) {
if (localHeadTask.acquireValidLock()) {
try {
+ runTask.getRunPeriod()));
}
}
} catch (IllegalStateException iex) {
}
// This exception will be thrown only if the
// Timer has been shutdown already.
shouldTerminate = true;
} finally {
}
}
}
synchronized (pool) {
}
}
shouldTerminate = true;
needReturn = false;
// rethrow Error here
throw new Error(e);
} finally {
// the thread may has returned already if shutdown is
// called.
if (needReturn) {
pool.returnThread(t);
}
}
if (shouldTerminate) {
// we may need to log something here!
break;
}
}
}
}
/**
* Scheduler is the one who handles the time to wait and assign a thread to
* the task when it is time. If there is no thread availabe when it is time
* to run a particular task, Scheduler will wait until thread available.
*/
private volatile boolean shouldTerminate;
private boolean beingNotified;
private long delay;
/**
* Constructor of Scheduler.
*
* @param pool The TimerPool the Scheduler belongs to
*/
this.shouldTerminate = false;
this.beingNotified = false;
this.delay = -1;
}
/**
* Sets the time (in ms) to wait.
*
* @param delay The time (in ms) to wait
*/
this.beingNotified = true;
this.notify();
}
/**
* Sets the time (in ms) to wait without notification.
*
* @param delay The time (in ms) to wait
*/
}
/**
* Terminates this Scheduler.
*/
public synchronized void terminate() {
this.shouldTerminate = true;
this.notify();
}
/**
* Implements run method with errors handling for Thread object.
*/
public void run() {
long localDelay = -1;
while (true) {
try {
synchronized (this) {
if (!shouldTerminate) {
if (delay > 0) {
if (beingNotified) {
beingNotified = false;
continue;
}
} else {
if (delay < 0) {
this.wait();
if (beingNotified) {
beingNotified = false;
continue;
}
}
}
}
}
if (shouldTerminate) {
break;
}
} catch (RuntimeException ex) {
} catch (Throwable t) {
throw new Error(t);
}
if (shouldTerminate) {
break;
}
}
}
}
}