cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From giac...@apache.org
Subject svn commit: rev 56675 - cocoon/trunk/src/java/org/apache/cocoon/components/thread
Date Fri, 05 Nov 2004 15:24:47 GMT
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 {@link RunnableManager} interface
+ * and is responsible to create {@link ThreadPool}s and run {@link Runnable}s
+ * in them as background commands.
+ * 
+ * <p>
+ * The configuration of the <code>DefaultRunnableManager</code>:
+ * <pre>
+ *   &lt;thread-factory&gt;org.apache.cocoon.components.thread.DefaultThreadFactory&lt;/thread-factory&gt;
+ *   &lt;thread-pools&gt;
+ *     &lt;thread-pool&gt;  
+ *       &lt;name&gt;default&lt;/name&gt;
+ *       &lt;priority&gt;NORM&lt;/priority&gt; &lt;!-- MIN | NORM | MAX --&gt; 
+ *       &lt;queue-size&gt;-1&lt;/queue-size&gt; &lt;!-- &lt;0 unbounded; ==0 no queue --&gt; 
+ *       &lt;max-pool-size&gt;-1&lt;/max-pool-size&gt; &lt;!-- &le;0 unbounded --&gt; 
+ *       &lt;min-pool-size&gt;2&lt;/min-pool-size&gt; &lt;!-- &le;0 not allowed --&gt;
+ *       &lt;keep-alive-time-ms&gt;20000&lt;/keep-alive-time-ms&gt;
+ *       &lt;block-policy&gt;RUN&lt;/block-policy&gt;
+ *       &lt;shutdown-graceful&gt;false&lt;/shutdown-graceful&gt;
+ *       &lt;shutdown-wait-time-ms&gt;-1&lt;/shutdown-wait-time-ms&gt;
+ *     &lt;/thread-pool&gt; 
+ *   &lt;/thread-pools&gt;
+ * </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 {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link 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 {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param threadPoolName The thread pool name to be used
+     * @param command The {@link 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 {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param command The {@link 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 {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param command The {@link 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 {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param command The {@link Runnable} to execute
+     */
+    public void execute( final Runnable command )
+    {
+        execute( DEFAULT_THREADPOOL_NAME, command, 0, 0 );
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param threadPoolName The thread pool name to be used
+     * @param command The {@link 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 {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param threadPoolName The thread pool name to be used
+     * @param command The {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link 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:info@otego.com">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 {@link ThreadPool} interface.
+ * Instances of this class are made by the {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *         Thread#NORM_PRIORITY}, or {@link 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 {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link 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 {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link 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 {@link ThreadPool}s of the {@link 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 {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, {@link Thread#MAX_PRIORITY}
+     */
+    void setPriority( int priority );
+
+    /**
+     * Create a new Thread for a {@link 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 {@link 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(  );
+}

Mime
View raw message