Author: giacomo Date: Fri Nov 5 07:24:45 2004 New Revision: 56675 Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/ cocoon/trunk/src/java/org/apache/cocoon/components/thread/BoundedQueue.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/ChannelWrapper.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultThreadPool.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/LinkedQueue.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/Queue.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/RunnableManager.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/SynchronousChannel.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/ThreadFactory.java cocoon/trunk/src/java/org/apache/cocoon/components/thread/ThreadPool.java Log: added first draft of Excalibur CommandManager replacement src/java/org/apache/cocoon/components/thread
Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/BoundedQueue.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/BoundedQueue.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,68 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +/** + * Efficient array-based bounded buffer class. Adapted from CPJ, chapter 8, + * which describes design. + * + * <p> + * [<a + * href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> + * Introduction to this package. </a>] + * </p> + * + * <p></p> + */ +public class BoundedQueue + extends EDU.oswego.cs.dl.util.concurrent.BoundedBuffer + implements Queue +{ + //~ Constructors ----------------------------------------------------------- + + /** + * Create a buffer with the current default capacity + */ + public BoundedQueue( ) + { + super( ); + } + + /** + * Create a BoundedQueue with the given capacity. + * + * @param capacity The capacity + * + * @exception IllegalArgumentException if capacity less or equal to zero + */ + public BoundedQueue( int capacity ) + throws IllegalArgumentException + { + super( capacity ); + } + + //~ Methods ---------------------------------------------------------------- + + /** + * DOCUMENT ME! + * + * @return + */ + public int getQueueSize( ) + { + return usedSlots_; + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/ChannelWrapper.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/ChannelWrapper.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,92 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +import EDU.oswego.cs.dl.util.concurrent.Channel; + + +/** + * Wrapper around a Channel implementation for constructor convenience + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version $Id$ + */ +public class ChannelWrapper + implements Channel +{ + //~ Instance fields -------------------------------------------------------- + + /** The wrapped Channel */ + private Channel m_channel; + + //~ Methods ---------------------------------------------------------------- + + /** + * DOCUMENT ME! + * + * @param channel DOCUMENT ME! + */ + public void setChannel( final Channel channel ) + { + m_channel = channel; + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.Puttable#offer(java.lang.Object, + * long) + */ + public boolean offer( final Object obj, + final long timeout ) + throws InterruptedException + { + return m_channel.offer( obj, timeout ); + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.Channel#peek() + */ + public Object peek( ) + { + return m_channel.peek( ); + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.Takable#poll(long) + */ + public Object poll( final long timeout ) + throws InterruptedException + { + return m_channel.poll( timeout ); + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.Puttable#put(java.lang.Object) + */ + public void put( final Object obj ) + throws InterruptedException + { + m_channel.put( obj ); + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.Takable#take() + */ + public Object take( ) + throws InterruptedException + { + return m_channel.take( ); + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,670 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +import org.apache.avalon.framework.activity.Disposable; +import org.apache.avalon.framework.configuration.Configurable; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.logger.Logger; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + + +/** + * The DefaultRunnableManager implements the [EMAIL PROTECTED] RunnableManager} interface + * and is responsible to create [EMAIL PROTECTED] ThreadPool}s and run [EMAIL PROTECTED] Runnable}s + * in them as background commands. + * + * <p> + * The configuration of the <code>DefaultRunnableManager</code>: + * <pre> + * <thread-factory>org.apache.cocoon.components.thread.DefaultThreadFactory</thread-factory> + * <thread-pools> + * <thread-pool> + * <name>default</name> + * <priority>NORM</priority> <!-- MIN | NORM | MAX --> + * <queue-size>-1</queue-size> <!-- <0 unbounded; ==0 no queue --> + * <max-pool-size>-1</max-pool-size> <!-- ≤0 unbounded --> + * <min-pool-size>2</min-pool-size> <!-- ≤0 not allowed --> + * <keep-alive-time-ms>20000</keep-alive-time-ms> + * <block-policy>RUN</block-policy> + * <shutdown-graceful>false</shutdown-graceful> + * <shutdown-wait-time-ms>-1</shutdown-wait-time-ms> + * </thread-pool> + * </thread-pools> + * </pre> + * </p> + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version $Id$ + */ +public class DefaultRunnableManager + extends AbstractLogEnabled + implements RunnableManager, Configurable, Disposable, Runnable +{ + //~ Static fields/initializers --------------------------------------------- + + /** The default [EMAIL PROTECTED] ThreadFactory} */ + public static final String DEFAULT_THREAD_FACTORY = + DefaultThreadFactory.class.getName( ); + + /** The default queue size */ + public static final int DEFAULT_QUEUE_SIZE = -1; + + /** The default maximum pool size */ + public static final int DEFAULT_MAX_POOL_SIZE = 5; + + /** The default minimum pool size */ + public static final int DEFAULT_MIN_POOL_SIZE = 5; + + /** The default thread priority */ + public static final String DEFAULT_THREAD_PRIORITY = "NORM"; + + /** The default keep alive time */ + public static final long DEFAULT_KEEP_ALIVE_TIME = 20000L; + + /** The default way to shutdown gracefully */ + public static final boolean DEFAULT_SHUTDOWN_GRACEFUL = false; + + /** The default shutdown waittime time */ + public static final int DEFAULT_SHUTDOWN_WAIT_TIME = -1; + + /** The default shutdown waittime time */ + public static final String DEFAULT_THREADPOOL_NAME = "default"; + + //~ Instance fields -------------------------------------------------------- + + /** The managed thread pools */ + final Map m_pools = new HashMap( ); + + /** The configured default ThreadFactory class instance */ + private Class m_defaultThreadFactoryClass; + + /** + * Sorted set of <code>ExecutionInfo</code> instances, based on their next + * execution time. + */ + protected SortedSet m_executionInfo = new TreeSet( ); + + //~ Methods ---------------------------------------------------------------- + + /** + * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) + */ + public void configure( final Configuration config ) + throws ConfigurationException + { + final String defaultThreadFactoryName = + config.getChild( "thread-factory" ).getValue( DEFAULT_THREAD_FACTORY ); + + try + { + m_defaultThreadFactoryClass = + Thread.currentThread( ).getContextClassLoader( ).loadClass( defaultThreadFactoryName ); + } + catch( final Exception ex ) + { + throw new ConfigurationException( "Cannot create instance of default thread factory " + + defaultThreadFactoryName, ex ); + } + + final Configuration [] threadpools = + config.getChildren( "thread-pools" ); + + for( int i = 0; i < threadpools.length; i++ ) + { + final DefaultThreadPool pool = configThreadPool( threadpools[ i ] ); + + if( getLogger( ).isInfoEnabled( ) ) + { + if( pool.isQueued( ) ) + { + final StringBuffer msg = new StringBuffer( ); + msg.append( "ThreadPool named \"" ).append( pool.getName( ) ); + msg.append( "\" created with queue-size=" ); + msg.append( pool.getQueueSize( ) ); + msg.append( ",max-pool-size=" ).append( pool.getMaximumPoolSize( ) ); + msg.append( ",min-pool-size=" ).append( pool.getMinimumPoolSize( ) ); + msg.append( ",priority=" ).append( pool.getPriority( ) ); + msg.append( ",keep-alive-time-ms=" ).append( pool.getKeepAliveTime( ) ); + msg.append( ",block-policy=\"" ).append( pool.getBlockPolicy( ) ); + msg.append( "\",shutdown-wait-time-ms=" ).append( pool.getShutdownWaitTimeMs( ) ); + getLogger( ).info( msg.toString( ) ); + } + else + { + final StringBuffer msg = new StringBuffer( ); + msg.append( "ThreadPool named \"" ).append( pool.getName( ) ); + msg.append( "\" created with no queue,max-pool-size=" ) + .append( pool.getMaximumPoolSize( ) ); + msg.append( ",min-pool-size=" ).append( pool.getMinimumPoolSize( ) ); + msg.append( ",priority=" ).append( pool.getPriority( ) ); + msg.append( ",keep-alive-time-ms=" ).append( pool.getKeepAliveTime( ) ); + msg.append( ",block-policy=" ).append( pool.getBlockPolicy( ) ); + msg.append( ",shutdown-wait-time-ms=" ).append( pool.getShutdownWaitTimeMs( ) ); + getLogger( ).info( msg.toString( ) ); + } + } + } + + // Check if a "default" pool has been created + final ThreadPool defaultThreadPool = + (ThreadPool)m_pools.get( DEFAULT_THREADPOOL_NAME ); + + if( null == defaultThreadPool ) + { + createPool( DEFAULT_THREADPOOL_NAME, DEFAULT_QUEUE_SIZE, + DEFAULT_MAX_POOL_SIZE, DEFAULT_MIN_POOL_SIZE, + getPriority( DEFAULT_THREAD_PRIORITY ), + DEFAULT_KEEP_ALIVE_TIME, + DefaultThreadPool.POLICY_DEFAULT, + DEFAULT_SHUTDOWN_GRACEFUL, DEFAULT_SHUTDOWN_WAIT_TIME ); + } + } + + /** + * Create a shared ThreadPool + * + * @param name The name of the thread pool + * @param queueSize The size of the queue + * @param maxPoolSize The maximum number of threads + * @param minPoolSize The maximum number of threads + * @param priority The priority of threads created by this pool. This is + * one of [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, or [EMAIL PROTECTED] Thread#MAX_PRIORITY} + * @param keepAliveTime How long should a thread be alive for new work to + * be done before it is GCed + * @param blockPolicy What's the blocking policy is resources are exhausted + * @param shutdownGraceful Should we wait for the queue to finish all + * pending commands? + * @param shutdownWaitTime After what time a normal shutdown should take + * into account if a graceful shutdown has not come to an end + */ + public void createPool( final String name, + final int queueSize, + final int maxPoolSize, + final int minPoolSize, + final int priority, + final long keepAliveTime, + final String blockPolicy, + final boolean shutdownGraceful, + final int shutdownWaitTime ) + { + createPool( new DefaultThreadPool( ), name, queueSize, maxPoolSize, + minPoolSize, priority, keepAliveTime, blockPolicy, + shutdownGraceful, shutdownWaitTime ); + } + + /** + * Create a private ThreadPool + * + * @param queueSize The size of the queue + * @param maxPoolSize The maximum number of threads + * @param minPoolSize The maximum number of threads + * @param priority The priority of threads created by this pool. This is + * one of [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, or [EMAIL PROTECTED] Thread#MAX_PRIORITY} + * @param keepAliveTime How long should a thread be alive for new work to + * be done before it is GCed + * @param blockPolicy What's the blocking policy is resources are exhausted + * @param shutdownGraceful Should we wait for the queue to finish all + * pending commands? + * @param shutdownWaitTime After what time a normal shutdown should take + * into account if a graceful shutdown has not come to an end + * + * @return A newly created <code>ThreadPool</code> + */ + public ThreadPool createPool( final int queueSize, + final int maxPoolSize, + final int minPoolSize, + final int priority, + final long keepAliveTime, + final String blockPolicy, + final boolean shutdownGraceful, + final int shutdownWaitTime ) + { + final DefaultThreadPool pool = new DefaultThreadPool( ); + final String name = "anon-" + pool.hashCode( ); + + return createPool( pool, name, queueSize, maxPoolSize, minPoolSize, + priority, keepAliveTime, blockPolicy, + shutdownGraceful, shutdownWaitTime ); + } + + /** + * @see org.apache.avalon.framework.activity.Disposable#dispose() + */ + public void dispose( ) + { + for( final Iterator i = m_pools.keySet( ).iterator( ); i.hasNext( ); ) + { + final DefaultThreadPool pool = (DefaultThreadPool)i.next( ); + pool.shutdown( ); + } + + m_pools.clear( ); + } + + /** + * Run a [EMAIL PROTECTED] Runnable} in the background using a [EMAIL PROTECTED] ThreadPool} + * + * @param threadPoolName The thread pool name to be used + * @param command The [EMAIL PROTECTED] Runnable} to execute + * @param delay the delay befor first run + * @param interval The interval for repeated runs + */ + public void execute( final String threadPoolName, + final Runnable command, + final long delay, + long interval ) + { + if( delay < 0 ) + { + throw new IllegalArgumentException( "delay < 0" ); + } + if( interval < 0 ) + { + throw new IllegalArgumentException( "interval < 0" ); + } + ThreadPool pool = (ThreadPool)m_pools.get( threadPoolName ); + + if( null == pool ) + { + getLogger( ).warn( "ThreadPool \"" + threadPoolName + + "\" is not known. Will use ThreadPool \"" + + DEFAULT_THREADPOOL_NAME + "\"" ); + pool = (ThreadPool)m_pools.get( DEFAULT_THREADPOOL_NAME ); + } + + new ExecutionInfo( pool, command, delay, interval, getLogger( ) ); + } + + /** + * Run a [EMAIL PROTECTED] Runnable} in the background using a [EMAIL PROTECTED] ThreadPool} + * + * @param command The [EMAIL PROTECTED] Runnable} to execute + * @param delay the delay befor first run + * @param interval The interval for repeated runs + */ + public void execute( final Runnable command, + final long delay, + final long interval ) + { + execute( DEFAULT_THREADPOOL_NAME, command, delay, interval ); + } + + /** + * Run a [EMAIL PROTECTED] Runnable} in the background using a [EMAIL PROTECTED] ThreadPool} + * + * @param command The [EMAIL PROTECTED] Runnable} to execute + * @param delay the delay befor first run + */ + public void execute( final Runnable command, + final long delay ) + { + execute( DEFAULT_THREADPOOL_NAME, command, delay, 0 ); + } + + /** + * Run a [EMAIL PROTECTED] Runnable} in the background using a [EMAIL PROTECTED] ThreadPool} + * + * @param command The [EMAIL PROTECTED] Runnable} to execute + */ + public void execute( final Runnable command ) + { + execute( DEFAULT_THREADPOOL_NAME, command, 0, 0 ); + } + + /** + * Run a [EMAIL PROTECTED] Runnable} in the background using a [EMAIL PROTECTED] ThreadPool} + * + * @param threadPoolName The thread pool name to be used + * @param command The [EMAIL PROTECTED] Runnable} to execute + * @param delay the delay befor first run + */ + public void execute( final String threadPoolName, + final Runnable command, + final long delay ) + { + execute( threadPoolName, command, delay, 0 ); + } + + /** + * Run a [EMAIL PROTECTED] Runnable} in the background using a [EMAIL PROTECTED] ThreadPool} + * + * @param threadPoolName The thread pool name to be used + * @param command The [EMAIL PROTECTED] Runnable} to execute + */ + public void execute( final String threadPoolName, + final Runnable command ) + { + execute( threadPoolName, command, 0, 0 ); + } + + /** + * The heart of the command manager + */ + public void run( ) + { + while( true ) + { + synchronized( m_executionInfo ) + { + try + { + if( m_executionInfo.size( ) > 0 ) + { + final ExecutionInfo info = + (ExecutionInfo)m_executionInfo.first( ); + final long delay = + info.m_nextRun - System.currentTimeMillis( ); + + if( delay > 0 ) + { + m_executionInfo.wait( delay ); + } + } + else + { + if(getLogger().isDebugEnabled() ) + { + getLogger().debug( "No commands available. Will just wait for one" ); + } + m_executionInfo.wait( ); + } + } + catch( final InterruptedException ie ) + { + if(getLogger().isDebugEnabled() ) + { + getLogger().debug( "I've been interrupted" ); + } + } + + final ExecutionInfo info = (ExecutionInfo)m_executionInfo.first( ); + final long delay = + info.m_nextRun - System.currentTimeMillis( ); + + if( delay < 0 ) + { + info.execute( ); + } + } + } + } + + /** + * DOCUMENT ME! + * + * @param priority The priority to set as string value. + * + * @return The priority as int value. + */ + private int getPriority( final String priority ) + { + if( "MIN".equalsIgnoreCase( priority ) ) + { + return Thread.MIN_PRIORITY; + } + else if( "NORM".equalsIgnoreCase( priority ) ) + { + return Thread.NORM_PRIORITY; + } + else if( "MAX".equalsIgnoreCase( priority ) ) + { + return Thread.MAX_PRIORITY; + } + else + { + return Thread.NORM_PRIORITY; + } + } + + /** + * DOCUMENT ME! + * + * @param config DOCUMENT ME! + * + * @return DOCUMENT ME! + * + * @throws ConfigurationException DOCUMENT ME! + */ + private DefaultThreadPool configThreadPool( final Configuration config ) + throws ConfigurationException + { + final String name = config.getChild( "name" ).getValue( ); + final int queueSize = + config.getChild( "queue-size" ).getValueAsInteger( DEFAULT_QUEUE_SIZE ); + final int maxPoolSize = + config.getChild( "max-pool-size" ).getValueAsInteger( DEFAULT_MAX_POOL_SIZE ); + int minPoolSize = + config.getChild( "min-pool-size" ).getValueAsInteger( DEFAULT_MIN_POOL_SIZE ); + + // make sure we have enough threads for the default thread pool as we + // need one for ourself + if( DEFAULT_THREADPOOL_NAME.equals( name ) && + ( minPoolSize < DEFAULT_MIN_POOL_SIZE ) ) + { + minPoolSize = DEFAULT_MIN_POOL_SIZE; + } + + final String priority = + config.getChild( "priority" ).getValue( DEFAULT_THREAD_PRIORITY ); + final long keepAliveTime = + config.getChild( "keep-alive-time-ms" ).getValueAsLong( DEFAULT_KEEP_ALIVE_TIME ); + final String blockPolicy = + config.getChild( "block-policy" ).getValue( DefaultThreadPool.POLICY_DEFAULT ); + final boolean shutdownGraceful = + config.getChild( "shutdown-graceful" ).getValueAsBoolean( DEFAULT_SHUTDOWN_GRACEFUL ); + final int shutdownWaitTime = + config.getChild( "shutdown-wait-time-ms" ).getValueAsInteger( DEFAULT_SHUTDOWN_WAIT_TIME ); + + return createPool( new DefaultThreadPool( ), name, queueSize, + maxPoolSize, minPoolSize, getPriority( priority ), + keepAliveTime, blockPolicy, shutdownGraceful, + shutdownWaitTime ); + } + + /** + * Create a ThreadPool + * + * @param pool DOCUMENT ME! + * @param name DOCUMENT ME! + * @param queueSize The size of the queue + * @param maxPoolSize The maximum number of threads + * @param minPoolSize The maximum number of threads + * @param priority The priority of threads created by this pool. This is + * one of [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, or [EMAIL PROTECTED] Thread#MAX_PRIORITY} + * @param keepAliveTime How long should a thread be alive for new work to + * be done before it is GCed + * @param blockPolicy What's the blocking policy is resources are exhausted + * @param shutdownGraceful Should we wait for the queue to finish all + * pending commands? + * @param shutdownWaitTime After what time a normal shutdown should take + * into account if a graceful shutdown has not come to an end + * + * @return A newly created <code>ThreadPool</code> + */ + private DefaultThreadPool createPool( final DefaultThreadPool pool, + final String name, + final int queueSize, + final int maxPoolSize, + final int minPoolSize, + final int priority, + final long keepAliveTime, + final String blockPolicy, + final boolean shutdownGraceful, + final int shutdownWaitTime ) + { + pool.enableLogging( getLogger( ).getChildLogger( name ) ); + pool.setName( name ); + + ThreadFactory factory = null; + + try + { + factory = + (ThreadFactory)m_defaultThreadFactoryClass.newInstance( ); + } + catch( final Exception ex ) + { + getLogger( ).warn( "Cannot instantiate a ThreadFactory from class " + + m_defaultThreadFactoryClass.getName( ) + + ". Will use a " + + DefaultThreadFactory.class.getName( ), ex ); + factory = new DefaultThreadFactory( ); + } + + factory.setPriority( priority ); + pool.setThreadFactory( factory ); + pool.setQueue( queueSize ); + pool.setMaximumPoolSize( maxPoolSize ); + pool.setMinimumPoolSize( minPoolSize ); + pool.setKeepAliveTime( keepAliveTime ); + pool.setBlockPolicy( blockPolicy ); + pool.setShutdownGraceful( shutdownGraceful ); + pool.setShutdownWaitTimeMs( shutdownWaitTime ); + + synchronized( m_pools ) + { + m_pools.put( name, pool ); + } + + return pool; + } + + //~ Inner Classes ---------------------------------------------------------- + + /** + * The $classType$ class ... + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version $Id$ + */ + private class ExecutionInfo + implements Comparable + { + //~ Instance fields ---------------------------------------------------- + + /** Our logger */ + final Logger m_logger; + + /** DOCUMENT ME! */ + final Runnable m_command; + + /** DOCUMENT ME! */ + final ThreadPool m_pool; + + /** DOCUMENT ME! */ + final long m_delay; + + /** DOCUMENT ME! */ + final long m_interval; + + /** DOCUMENT ME! */ + long m_nextRun = 0; + + //~ Constructors ------------------------------------------------------- + + /** + * Creates a new ExecutionInfo object. + * + * @param pool DOCUMENT ME! + * @param command DOCUMENT ME! + * @param delay DOCUMENT ME! + * @param interval DOCUMENT ME! + * @param logger DOCUMENT ME! + */ + ExecutionInfo( final ThreadPool pool, + final Runnable command, + final long delay, + final long interval, + final Logger logger ) + { + m_pool = pool; + m_command = command; + m_delay = delay; + m_interval = interval; + m_logger = logger; + m_nextRun = System.currentTimeMillis( ) + delay; + + synchronized( m_executionInfo ) + { + m_executionInfo.add( this ); + m_executionInfo.notifyAll( ); + } + } + + //~ Methods ------------------------------------------------------------ + + /** + * DOCUMENT ME! + * + * @param other DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public int compareTo( final Object other ) + { + final ExecutionInfo otherInfo = (ExecutionInfo)other; + + return (int)( m_nextRun - otherInfo.m_nextRun ); + } + + /** + * DOCUMENT ME! + */ + void execute( ) + { + synchronized( m_executionInfo ) + { + m_executionInfo.remove( this ); + m_nextRun = ( ( m_interval > 0 ) + ? ( System.currentTimeMillis( ) + m_interval ) : 0 ); + + + if( m_nextRun > 0 ) + { + m_executionInfo.add( this ); + m_executionInfo.notifyAll( ); + } + } + + try + { + m_pool.execute( m_command ); + } + catch( final InterruptedException ie ) + { + if( m_logger.isDebugEnabled( ) ) + { + m_logger.debug( m_command + " has been interrupted" ); + } + } + catch( final Throwable t ) + { + m_logger.error( "Exception thrown by Command " + m_command, t ); + } + } + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,58 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + + +/** + * This class is responsible to create new Thread instances to run a command. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Otego AG, Switzerland</a> + * @version $Id$ + */ +public class DefaultThreadFactory + implements ThreadFactory, EDU.oswego.cs.dl.util.concurrent.ThreadFactory +{ + //~ Instance fields -------------------------------------------------------- + + /** The priority of newly created Threads */ + private int m_priority = Thread.NORM_PRIORITY; + + /** + * @see org.apache.cocoon.components.thread.ThreadFactory#setPriority(int) + */ + public void setPriority( final int priority ) + { + if( ( Thread.MAX_PRIORITY == priority ) || + ( Thread.MIN_PRIORITY == priority ) || + ( Thread.NORM_PRIORITY == priority ) ) + { + m_priority = priority; + } + } + + //~ Methods ---------------------------------------------------------------- + + /** + * @see EDU.oswego.cs.dl.util.concurrent.ThreadFactory#newThread(java.lang.Runnable) + */ + public Thread newThread( final Runnable command ) + { + final Thread thread = new Thread( command ); + thread.setPriority( m_priority ); + + return thread; + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultThreadPool.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/DefaultThreadPool.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,343 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +import org.apache.avalon.framework.logger.LogEnabled; +import org.apache.avalon.framework.logger.Logger; + +import EDU.oswego.cs.dl.util.concurrent.PooledExecutor; + + +/** + * The DefaultThreadPool class implements the [EMAIL PROTECTED] ThreadPool} interface. + * Instances of this class are made by the [EMAIL PROTECTED] RunnableManager} passing a + * configuration into the <code>configure</code> method. + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version CVS $Id: DefaultThreadPool.java,v 1.5 2004/06/23 20:25:43 giacomo Exp $ + */ +public class DefaultThreadPool + extends PooledExecutor + implements ThreadPool, LogEnabled +{ + //~ Static fields/initializers --------------------------------------------- + + /** Default ThreadPool block policy */ + public static final String POLICY_DEFAULT = POLICY_RUN; + + //~ Instance fields -------------------------------------------------------- + + /** Wrapps a channel */ + private ChannelWrapper m_channelWrapper; + + /** Our logger */ + private Logger m_logger; + + /** The Queue */ + private Queue m_queue; + + /** The blocking policy */ + private String m_blockPolicy; + + /** The name of this thread pool */ + private String m_name; + + /** Should we wait for running jobs to terminate on shutdown ? */ + private boolean m_shutdownGraceful; + + /** The priority of threads */ + private int m_priority; + + /** The maximum queue size */ + private int m_queueSize; + + /** How long to wait for running jobs to terminate on disposition */ + private int m_shutdownWaitTimeMs; + + //~ Constructors ----------------------------------------------------------- + + /** + * Create a new pool. + */ + DefaultThreadPool( ) + { + this( new ChannelWrapper( ) ); + } + + /** + * Create a new pool. + * + * @param channel DOCUMENT ME! + */ + private DefaultThreadPool( final ChannelWrapper channel ) + { + super( channel ); + m_channelWrapper = channel; + } + + //~ Methods ---------------------------------------------------------------- + + /** + * DOCUMENT ME! + * + * @return Returns the blockPolicy. + */ + public String getBlockPolicy( ) + { + return m_blockPolicy; + } + + /** + * DOCUMENT ME! + * + * @return size of queue (0 if isQueued() == false) + * + * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize() + */ + public int getMaximumQueueSize( ) + { + return m_queueSize; + } + + /** + * @see org.apache.cocoon.components.thread.ThreadPool#getName() + */ + public String getName( ) + { + return m_name; + } + + /** + * Get hte priority used to create Threads + * + * @return [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, or [EMAIL PROTECTED] Thread#MAX_PRIORITY} + */ + public int getPriority( ) + { + return m_priority; + } + + /** + * DOCUMENT ME! + * + * @return size of queue (0 if isQueued() == false) + * + * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize() + */ + public int getQueueSize( ) + { + return m_queue.getQueueSize( ); + } + + /** + * Whether this DefaultThreadPool has a queue + * + * @return Returns the m_isQueued. + * + * @see org.apache.cocoon.components.thread.ThreadPool#isQueued() + */ + public boolean isQueued( ) + { + return m_queueSize != 0; + } + + /** + * Set the logger + * + * @param logger + * + * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger) + */ + public void enableLogging( Logger logger ) + { + m_logger = logger; + } + + /** + * @see org.apache.cocoon.components.thread.ThreadPool#shutdownGraceful() + */ + public void shutdown( ) + { + if( m_shutdownGraceful ) + { + shutdownAfterProcessingCurrentlyQueuedTasks( ); + } + else + { + shutdownNow( ); + } + + try + { + if( getShutdownWaitTimeMs( ) > 0 ) + { + if( ! awaitTerminationAfterShutdown( getShutdownWaitTimeMs( ) ) ) + { + getLogger( ).warn( "running commands have not terminated within " + + getShutdownWaitTimeMs( ) + + "ms. Will shut them down by interruption" ); + interruptAll( ); + shutdownNow( ); + } + } + + awaitTerminationAfterShutdown( ); + } + catch( final InterruptedException ie ) + { + getLogger( ).error( "cannot shutdown ThreadPool", ie ); + } + } + + /** + * Set the blocking policy + * + * @param blockPolicy The blocking policy value + */ + void setBlockPolicy( final String blockPolicy ) + { + if( POLICY_ABORT.equalsIgnoreCase( blockPolicy ) ) + { + abortWhenBlocked( ); + } + else if( POLICY_DISCARD.equalsIgnoreCase( blockPolicy ) ) + { + discardWhenBlocked( ); + } + else if( POLICY_DISCARD_OLDEST.equalsIgnoreCase( blockPolicy ) ) + { + discardOldestWhenBlocked( ); + } + else if( POLICY_RUN.equalsIgnoreCase( blockPolicy ) ) + { + runWhenBlocked( ); + } + else if( POLICY_WAIT.equalsIgnoreCase( blockPolicy ) ) + { + waitWhenBlocked( ); + } + else + { + final StringBuffer msg = new StringBuffer( ); + msg.append( "WARNING: Unknown block-policy configuration \"" ) + .append( blockPolicy ); + msg.append( "\". Should be one of \"" ).append( POLICY_ABORT ); + msg.append( "\",\"" ).append( POLICY_DISCARD ); + msg.append( "\",\"" ).append( POLICY_DISCARD_OLDEST ); + msg.append( "\",\"" ).append( POLICY_RUN ); + msg.append( "\",\"" ).append( POLICY_WAIT ); + msg.append( "\". Will use \"" ).append( POLICY_DEFAULT ).append( "\"" ); + getLogger( ).warn( msg.toString( ) ); + setBlockPolicy( POLICY_DEFAULT ); + } + } + + /** + * DOCUMENT ME! + * + * @param name The name to set. + */ + void setName( String name ) + { + m_name = name; + } + + /** + * DOCUMENT ME! + * + * @param queueSize DOCUMENT ME! + */ + void setQueue( final int queueSize ) + { + if( queueSize != 0 ) + { + if( queueSize > 0 ) + { + m_queue = new BoundedQueue( queueSize ); + } + else + { + m_queue = new LinkedQueue( ); + } + } + else + { + m_queue = new SynchronousChannel( ); + } + + m_queueSize = queueSize; + m_channelWrapper.setChannel( m_queue ); + } + + /** + * DOCUMENT ME! + * + * @param shutdownGraceful The shutdownGraceful to set. + */ + void setShutdownGraceful( boolean shutdownGraceful ) + { + m_shutdownGraceful = shutdownGraceful; + } + + /** + * DOCUMENT ME! + * + * @return Returns the shutdownGraceful. + */ + boolean isShutdownGraceful( ) + { + return m_shutdownGraceful; + } + + /** + * DOCUMENT ME! + * + * @param shutdownWaitTimeMs The shutdownWaitTimeMs to set. + */ + void setShutdownWaitTimeMs( int shutdownWaitTimeMs ) + { + m_shutdownWaitTimeMs = shutdownWaitTimeMs; + } + + /** + * DOCUMENT ME! + * + * @return Returns the shutdownWaitTimeMs. + */ + int getShutdownWaitTimeMs( ) + { + return m_shutdownWaitTimeMs; + } + + /** + * Get our <code>Logger</code> + * + * @return our <code>Logger</code> + */ + private Logger getLogger( ) + { + return m_logger; + } + + /** + * @param priority The priority to set. + */ + void setPriority( final int priority ) + { + m_priority = priority; + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/LinkedQueue.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/LinkedQueue.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,74 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +/** + * A linked list based channel implementation. The algorithm avoids contention + * between puts and takes when the queue is not empty. Normally a put and a + * take can proceed simultaneously. (Although it does not allow multiple + * concurrent puts or takes.) This class tends to perform more efficently than + * other Queue implementations in producer/consumer applications. + * + * <p> + * [<a + * href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> + * Introduction to this package. </a>] + * </p> + */ +public class LinkedQueue + extends EDU.oswego.cs.dl.util.concurrent.LinkedQueue + implements Queue +{ + //~ Instance fields -------------------------------------------------------- + + /** The size */ + protected int m_size = 0; + + //~ Methods ---------------------------------------------------------------- + + /** + * @see org.apache.cocoon.components.thread.Queue#getQueueSize() + */ + public int getQueueSize( ) + { + return m_size; + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.LinkedQueue#extract() + */ + protected synchronized Object extract( ) + { + synchronized( head_ ) + { + if( head_.next != null ) + { + --m_size; + } + + return super.extract( ); + } + } + + /** + * @see EDU.oswego.cs.dl.util.concurrent.LinkedQueue#insert(java.lang.Object) + */ + protected void insert( final Object object ) + { + super.insert( object ); + ++m_size; + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/Queue.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/Queue.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +/** + * Extension to add queue size reporting + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version CVS $Id$ + * + * @see EDU.oswego.cs.dl.util.concurrent.Channel + */ +public interface Queue + extends EDU.oswego.cs.dl.util.concurrent.Channel +{ + //~ Methods ---------------------------------------------------------------- + + /** + * get the current queue size + * + * @return The current queue size + */ + int getQueueSize( ); +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/RunnableManager.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/RunnableManager.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,149 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +/** + * The RunnableManager interface describes the functionality of an + * implementation running commands in the background. + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version CVS $Id$ + */ +public interface RunnableManager +{ + //~ Instance fields -------------------------------------------------------- + + /** The role name */ + String ROLE = RunnableManager.class.getName( ); + + //~ Methods ---------------------------------------------------------------- + + /** + * Create a shared ThreadPool with a specific [EMAIL PROTECTED] ThreadFactory} + * + * @param name The name of the thread pool + * @param queueSize The size of the queue + * @param maxPoolSize The maximum number of threads + * @param minPoolSize The maximum number of threads + * @param priority The priority of threads created by this pool. This is + * one of [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, or [EMAIL PROTECTED] Thread#MAX_PRIORITY} + * @param keepAliveTime How long should a thread be alive for new work to + * be done before it is GCed + * @param blockPolicy What's the blocking policy is resources are exhausted + * @param shutdownGraceful Should we wait for the queue to finish all + * pending commands? + * @param shutdownWaitTime After what time a normal shutdown should take + * into account if a graceful shutdown has not come to an end + */ + void createPool( String name, + int queueSize, + int maxPoolSize, + int minPoolSize, + int priority, + long keepAliveTime, + String blockPolicy, + boolean shutdownGraceful, + int shutdownWaitTime ); + + /** + * Create a private ThreadPool with a specific [EMAIL PROTECTED] ThreadFactory} + * + * @param queueSize The size of the queue + * @param maxPoolSize The maximum number of threads + * @param minPoolSize The maximum number of threads + * @param priority The priority of threads created by this pool. This is + * one of [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, or [EMAIL PROTECTED] Thread#MAX_PRIORITY} + * @param keepAliveTime How long should a thread be alive for new work to + * be done before it is GCed + * @param blockPolicy What's the blocking policy is resources are exhausted + * @param shutdownGraceful Should we wait for the queue to finish all + * pending commands? + * @param shutdownWaitTime After what time a normal shutdown should take + * into account if a graceful shutdown has not come to an end + * + * @return The newly created <code>ThreadPool</code> + */ + ThreadPool createPool( int queueSize, + int maxPoolSize, + int minPoolSize, + int priority, + long keepAliveTime, + String blockPolicy, + boolean shutdownGraceful, + int shutdownWaitTime ); + + /** + * Immediate Execution of a runnable in the background + * + * @param command The command to execute + */ + void execute( Runnable command ); + + /** + * Immediate Execution of a runnable in the background + * + * @param command The command to execute + * @param delay The delay before first run + */ + void execute( Runnable command, + long delay ); + + /** + * Immediate Execution of a runnable in the background + * + * @param command The command to execute + * @param delay The delay before first run + * @param interval The interval of repeated runs + */ + void execute( Runnable command, + long delay, + long interval ); + + /** + * Immediate Execution of a runnable in the background + * + * @param threadPoolName The thread pool to use + * @param command The command to execute + */ + void execute( String threadPoolName, + Runnable command ); + + /** + * Immediate Execution of a runnable in the background + * + * @param threadPoolName The thread pool to use + * @param command The command to execute + * @param delay The delay before first run + */ + void execute( String threadPoolName, + Runnable command, + long delay ); + + /** + * Delayed and repeated Execution of a runnable in the background + * + * @param threadPoolName The thread pool to use + * @param command The command to execute + * @param delay The delay before first run + * @param interval The interval of repeated runs + */ + void execute( String threadPoolName, + Runnable command, + long delay, + long interval ); +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/SynchronousChannel.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/SynchronousChannel.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier; +import EDU.oswego.cs.dl.util.concurrent.Rendezvous; + + +/** + * A rendezvous channel, similar to those used in CSP and Ada. Each put must + * wait for a take, and vice versa. Synchronous channels are well suited for + * handoff designs, in which an object running in one thread must synch up + * with an object running in another thread in order to hand it some + * information, event, or task. + * + * <p> + * If you only need threads to synch up without exchanging information, + * consider using a Barrier. If you need bidirectional exchanges, consider + * using a Rendezvous. + * </p> + * + * <p></p> + * + * <p> + * [<a + * href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> + * Introduction to this package. </a>] + * </p> + * + * @see CyclicBarrier + * @see Rendezvous + */ +public class SynchronousChannel + extends EDU.oswego.cs.dl.util.concurrent.SynchronousChannel + implements Queue +{ + //~ Methods ---------------------------------------------------------------- + + /** + * @see org.apache.cocoon.components.thread.Queue#getQueueSize() + */ + public int getQueueSize( ) + { + return 0; + } +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/ThreadFactory.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/ThreadFactory.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,45 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +/** + * The ThreadFactory interface describes the responability of Factories + * creating Thread for [EMAIL PROTECTED] ThreadPool}s of the [EMAIL PROTECTED] RunnableManager} + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version CVS $Id$ + */ +public interface ThreadFactory extends EDU.oswego.cs.dl.util.concurrent.ThreadFactory +{ + //~ Methods ---------------------------------------------------------------- + + /** + * Set the priority newly created <code>Thread</code>s should have + * + * @param priority One of [EMAIL PROTECTED] Thread#MIN_PRIORITY}, [EMAIL PROTECTED] + * Thread#NORM_PRIORITY}, [EMAIL PROTECTED] Thread#MAX_PRIORITY} + */ + void setPriority( int priority ); + + /** + * Create a new Thread for a [EMAIL PROTECTED] Runnable} command + * + * @param command The <code>Runnable</code> + * + * @return new <code>Thread</code> + */ + Thread newThread( Runnable command ); +} Added: cocoon/trunk/src/java/org/apache/cocoon/components/thread/ThreadPool.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/thread/ThreadPool.java Fri Nov 5 07:24:45 2004 @@ -0,0 +1,144 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * 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.apache.cocoon.components.thread; + +/** + * The ThreadPool interface gives access to methods needed to inspect and use + * of a pool of threads + * + * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a> + * @version CVS $Id: ThreadPool.java,v 1.1 2004/06/16 14:39:21 giacomo Exp $ + */ +public interface ThreadPool +{ + //~ Instance fields -------------------------------------------------------- + + /** ThreadPool block policy ABORT */ + String POLICY_ABORT = "ABORT"; + + /** ThreadPool block policy DISCARD */ + String POLICY_DISCARD = "DISCARD"; + + /** ThreadPool block policy DISCARD-OLDEST */ + String POLICY_DISCARD_OLDEST = "DISCARDOLDEST"; + + /** ThreadPool block policy RUN */ + String POLICY_RUN = "RUN"; + + /** ThreadPool block policy WAIT */ + String POLICY_WAIT = "WAIT"; + + /** The Role name */ + String ROLE = ThreadPool.class.getName( ); + + //~ Methods ---------------------------------------------------------------- + + /** + * The blocking policy used + * + * @return DOCUMENT ME! + */ + String getBlockPolicy( ); + + /** + * How long will a thread in this pool be idle before it is allowed to be + * garbage collected + * + * @return maximum idle time + */ + long getKeepAliveTime( ); + + /** + * How many threads are in this pool at maximum + * + * @return maximum size of pool + */ + int getMaximumPoolSize( ); + + /** + * Maximum size of the queue + * + * @return current size of queue + */ + int getMaximumQueueSize( ); + + /** + * How many threads are in this pool at minimum + * + * @return minimum size of pool + */ + int getMinimumPoolSize( ); + + /** + * The Name of this thread pool + * + * @return The name + */ + String getName( ); + + /** + * How many threads are currently in this pool + * + * @return current size of pool + */ + int getPoolSize( ); + + /** + * Get the thread priority used by this pool + * + * @return current size of queue + */ + int getPriority( ); + + /** + * Current size of the queue + * + * @return current size of queue + */ + int getQueueSize( ); + + /** + * Whether this ThreadPool has a queue + * + * @return Returns true if this ThreadPool has a queue + */ + boolean isQueued( ); + + /** + * Returns true if a shutDown method has succeeded in terminating all + * threads + * + * @return Whether a shutDown method has succeeded in terminating all + * threads + */ + boolean isTerminatedAfterShutdown( ); + + /** + * Execute a command using this pool + * + * @param command a [EMAIL PROTECTED] Runnable} to execute + * + * @throws InterruptedException In case of interruption + */ + void execute( Runnable command ) + throws InterruptedException; + + /** + * Terminates all threads possibly awaiting processing all elements + * currently in queue. + */ + void shutdown( ); +}