001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.tomcat.util.threads;
018:
019: /**
020: * The reaper is a background thread with which ticks every minute
021: * and calls registered objects to allow reaping of old session
022: * data.
023: *
024: * @author James Duncan Davidson [duncan@eng.sun.com]
025: * @author Costin Manolache
026: */
027: public class Reaper extends Thread {
028: private boolean daemon = false;
029:
030: public Reaper() {
031: if (daemon)
032: this .setDaemon(true);
033: this .setName("TomcatReaper");
034: }
035:
036: public Reaper(String name) {
037: if (daemon)
038: this .setDaemon(true);
039: this .setName(name);
040: }
041:
042: private long interval = 1000 * 60; //ms
043:
044: // XXX TODO Allow per/callback interval, find next, etc
045: // Right now the "interval" is used for all callbacks
046: // and it represent a sleep between runs.
047:
048: ThreadPoolRunnable cbacks[] = new ThreadPoolRunnable[30]; // XXX max
049: Object tdata[][] = new Object[30][]; // XXX max
050: int count = 0;
051:
052: /** Adding and removing callbacks is synchronized
053: */
054: Object lock = new Object();
055: static boolean running = true;
056:
057: // XXX Should be called 'interval' not defaultInterval
058:
059: public void setDefaultInterval(long t) {
060: interval = t;
061: }
062:
063: public long getDefaultIntervale() {
064: return interval;
065: }
066:
067: public int addCallback(ThreadPoolRunnable c, int interval) {
068: synchronized (lock) {
069: cbacks[count] = c;
070: count++;
071: return count - 1;
072: }
073: }
074:
075: public void removeCallback(int idx) {
076: synchronized (lock) {
077: count--;
078: cbacks[idx] = cbacks[count];
079: cbacks[count] = null;
080: }
081: }
082:
083: public void startReaper() {
084: running = true;
085: this .start();
086: }
087:
088: public synchronized void stopReaper() {
089: running = false;
090: System.out.println("Stop reaper ");
091: this .interrupt(); // notify() doesn't stop sleep
092: }
093:
094: public void run() {
095: while (running) {
096: if (!running)
097: break;
098: try {
099: Thread.sleep(interval);
100: } catch (InterruptedException ie) {
101: // sometimes will happen
102: }
103:
104: if (!running)
105: break;
106: for (int i = 0; i < count; i++) {
107: ThreadPoolRunnable callB = cbacks[i];
108: // it may be null if a callback is removed.
109: // I think the code is correct
110: if (callB != null) {
111: callB.runIt(tdata[i]);
112: }
113: if (!running)
114: break;
115: }
116: }
117: }
118: }
|