+++ /dev/null
-/*\r
- * Copyright 1999-2004 The Apache Software Foundation\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package org.apache.tomcat.util.threads;\r
-\r
-import org.apache.tomcat.util.buf.TimeStamp;\r
-\r
-/**\r
- * Expire unused objects. \r
- * \r
- */\r
-public final class Expirer implements ThreadPoolRunnable\r
-{\r
- \r
- private static org.apache.commons.logging.Log log=\r
- org.apache.commons.logging.LogFactory.getLog(Expirer.class );\r
- \r
- // We can use Event/Listener, but this is probably simpler\r
- // and more efficient\r
- public static interface ExpireCallback {\r
- public void expired( TimeStamp o );\r
- }\r
- \r
- private int checkInterval = 60;\r
- private Reaper reaper;\r
- ExpireCallback expireCallback;\r
-\r
- public Expirer() {\r
- }\r
-\r
- // ------------------------------------------------------------- Properties\r
- public int getCheckInterval() {\r
- return checkInterval;\r
- }\r
-\r
- public void setCheckInterval(int checkInterval) {\r
- this.checkInterval = checkInterval;\r
- }\r
-\r
- public void setExpireCallback( ExpireCallback cb ) {\r
- expireCallback=cb;\r
- }\r
- \r
- // -------------------- Managed objects --------------------\r
- static final int INITIAL_SIZE=8;\r
- TimeStamp managedObjs[]=new TimeStamp[INITIAL_SIZE];\r
- TimeStamp checkedObjs[]=new TimeStamp[INITIAL_SIZE];\r
- int managedLen=managedObjs.length;\r
- int managedCount=0;\r
- \r
- public void addManagedObject( TimeStamp ts ) {\r
- synchronized( managedObjs ) {\r
- if( managedCount >= managedLen ) {\r
- // What happens if expire is on the way ? Nothing,\r
- // expire will do it's job on the old array ( GC magic )\r
- // and the expired object will be marked as such\r
- // Same thing would happen ( and did ) with Hashtable\r
- TimeStamp newA[]=new TimeStamp[ 2 * managedLen ];\r
- System.arraycopy( managedObjs, 0, newA, 0, managedLen);\r
- managedObjs = newA;\r
- managedLen = 2 * managedLen;\r
- }\r
- managedObjs[managedCount]=ts;\r
- managedCount++;\r
- }\r
- }\r
-\r
- public void removeManagedObject( TimeStamp ts ) {\r
- for( int i=0; i< managedCount; i++ ) {\r
- if( ts == managedObjs[i] ) {\r
- synchronized( managedObjs ) {\r
- managedCount--;\r
- managedObjs[ i ] = managedObjs[managedCount];\r
- managedObjs[managedCount] = null;\r
- }\r
- return;\r
- }\r
- }\r
- }\r
- \r
- // --------------------------------------------------------- Public Methods\r
-\r
- public void start() {\r
- // Start the background reaper thread\r
- if( reaper==null) {\r
- reaper=new Reaper("Expirer");\r
- reaper.addCallback( this, checkInterval * 1000 );\r
- }\r
- \r
- reaper.startReaper();\r
- }\r
-\r
- public void stop() {\r
- reaper.stopReaper();\r
- }\r
-\r
-\r
- // -------------------------------------------------------- Private Methods\r
-\r
- // ThreadPoolRunnable impl\r
-\r
- public Object[] getInitData() {\r
- return null;\r
- }\r
-\r
- public void runIt( Object td[] ) {\r
- long timeNow = System.currentTimeMillis();\r
- if( log.isTraceEnabled() ) log.trace( "Checking " + timeNow );\r
- int checkedCount;\r
- synchronized( managedObjs ) {\r
- checkedCount=managedCount;\r
- if(checkedObjs.length < checkedCount)\r
- checkedObjs = new TimeStamp[managedLen];\r
- System.arraycopy( managedObjs, 0, checkedObjs, 0, checkedCount);\r
- }\r
- for( int i=0; i< checkedCount; i++ ) {\r
- TimeStamp ts=checkedObjs[i];\r
- checkedObjs[i] = null;\r
- \r
- if (ts==null || !ts.isValid())\r
- continue;\r
- \r
- long maxInactiveInterval = ts.getMaxInactiveInterval();\r
- if( log.isTraceEnabled() ) log.trace( "TS: " + maxInactiveInterval + " " +\r
- ts.getLastAccessedTime());\r
- if (maxInactiveInterval < 0)\r
- continue;\r
- \r
- long timeIdle = timeNow - ts.getThisAccessedTime();\r
- \r
- if (timeIdle >= maxInactiveInterval) {\r
- if( expireCallback != null ) {\r
- if( log.isDebugEnabled() )\r
- log.debug( ts + " " + timeIdle + " " +\r
- maxInactiveInterval );\r
- expireCallback.expired( ts );\r
- }\r
- }\r
- }\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright 1999-2004 The Apache Software Foundation\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package org.apache.tomcat.util.threads;\r
-\r
-\r
-/**\r
- * The reaper is a background thread with which ticks every minute\r
- * and calls registered objects to allow reaping of old session\r
- * data.\r
- * \r
- * @author James Duncan Davidson [duncan@eng.sun.com]\r
- * @author Costin Manolache\r
- */\r
-public class Reaper extends Thread {\r
- \r
- \r
- private static org.apache.commons.logging.Log log=\r
- org.apache.commons.logging.LogFactory.getLog(Reaper.class );\r
- \r
- private boolean daemon = false;\r
-\r
- public Reaper() {\r
- if (daemon)\r
- this.setDaemon(true);\r
- this.setName("TomcatReaper");\r
- }\r
-\r
- public Reaper(String name) {\r
- if (daemon)\r
- this.setDaemon(true);\r
- this.setName(name);\r
- }\r
-\r
- private long interval = 1000 * 60; //ms\r
-\r
- // XXX TODO Allow per/callback interval, find next, etc\r
- // Right now the "interval" is used for all callbacks\r
- // and it represent a sleep between runs.\r
-\r
- ThreadPoolRunnable cbacks[] = new ThreadPoolRunnable[30]; // XXX max\r
- Object tdata[][] = new Object[30][]; // XXX max\r
- int count = 0;\r
-\r
- /** Adding and removing callbacks is synchronized\r
- */\r
- Object lock = new Object();\r
- static boolean running = true;\r
-\r
- // XXX Should be called 'interval' not defaultInterval\r
-\r
- public void setDefaultInterval(long t) {\r
- interval = t;\r
- }\r
-\r
- public long getDefaultIntervale() {\r
- return interval;\r
- }\r
-\r
- public int addCallback(ThreadPoolRunnable c, int interval) {\r
- synchronized (lock) {\r
- cbacks[count] = c;\r
- count++;\r
- return count - 1;\r
- }\r
- }\r
-\r
- public void removeCallback(int idx) {\r
- synchronized (lock) {\r
- count--;\r
- cbacks[idx] = cbacks[count];\r
- cbacks[count] = null;\r
- }\r
- }\r
-\r
- public void startReaper() {\r
- running = true;\r
- this.start();\r
- }\r
-\r
- public synchronized void stopReaper() {\r
- running = false;\r
- if (log.isDebugEnabled())\r
- log.debug("Stop reaper ");\r
- this.interrupt(); // notify() doesn't stop sleep\r
- }\r
-\r
- public void run() {\r
- while (running) {\r
- if (!running)\r
- break;\r
- try {\r
- Thread.sleep(interval);\r
- } catch (InterruptedException ie) {\r
- // sometimes will happen\r
- }\r
-\r
- if (!running)\r
- break;\r
- for (int i = 0; i < count; i++) {\r
- ThreadPoolRunnable callB = cbacks[i];\r
- // it may be null if a callback is removed.\r
- // I think the code is correct\r
- if (callB != null) {\r
- callB.runIt(tdata[i]);\r
- }\r
- if (!running)\r
- break;\r
- }\r
- }\r
- }\r
-}\r