cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jheym...@apache.org
Subject svn commit: r330548 [27/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...
Date Thu, 03 Nov 2005 14:00:48 GMT
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2002-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.store.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.store.StoreJanitor;
+
+/**
+ * This class is a implentation of a StoreJanitor. Store classes
+ * can register to the StoreJanitor. When memory is too low,
+ * the StoreJanitor frees the registered caches until memory is normal.
+ *
+ * <p>A few parameters can be used:
+ * <UL>
+ *  <LI><B>freememory</B>: How many bytes shall be always free in the JVM (Default: 1mb)</LI>
+ *  <LI><B>heapsize</B>: Maximum possible size of the JVM memory consumption (Default: 64mb)</LI>
+ *  <LI><B>cleanupthreadinterval</B>: How often (sec) shall run the cleanup thread (Default: 10s)</LI>
+ *  <LI><B>adaptivethreadinterval</B> (experimental): Enable adaptive algorithm to determine thread interval
+ *      (Default: false) When true, <code>cleanupthreadinterval</code> defines the maximum cleanup interval.
+ *      Cleanup interval then is determined based on the memory fill rate: the faster memory is filled in,
+ *      and the less free memory is left, the shorter is the cleanup time.</LI>
+ *  <LI><B>threadpriority</B>: priority of the thread (1-10). (Default: 10)</LI>
+ *  <LI><B>percent_to_free</B>: What fraction of the store to free when memory is low (1-100). (Default: 10%)</LI>
+ *  <LI><B>invokegc</B>: Invoke the gc on low memory first (true|false; default: false)</LI>
+ * </UL></p>
+ *
+ * @avalon.component
+ * @avalon.service type=StoreJanitor
+ * @x-avalon.info name=store-janitor
+ * @x-avalon.lifestyle type=singleton
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Id: StoreJanitorImpl.java 325932 2005-10-17 17:00:55Z sylvain $
+ */
+public class StoreJanitorImpl extends AbstractLogEnabled
+                              implements StoreJanitor, Parameterizable, ThreadSafe,
+                                         Initializable, Disposable, 
+                                         Runnable {
+
+    // Note: this class doesn't need to be Startable. This allows the janitor thread to be
+    // lazily created the first time a store registers itsefl
+
+    // Configuration parameters
+    private int minFreeMemory = -1;
+    private int maxHeapSize = -1;
+    private int threadInterval = -1;
+    private int minThreadInterval = 500;
+    private boolean adaptiveThreadInterval;
+    private int priority = -1;
+    private double fraction;
+
+    private Runtime jvm;
+    private ArrayList storelist;
+    private int index = -1;
+
+    /** Should the gc be called on low memory? */
+    protected boolean invokeGC;
+
+    private boolean doRun;
+
+    /**
+     * Amount of memory in use before sleep(). Must be initially set a resonable
+     * value; ie. <code>memoryInUse()</code>
+     */
+    protected long inUse;
+
+    private boolean firstRun = true;
+
+    /** The calculated delay for the next checker run in ms */
+    protected long interval = Long.MAX_VALUE;
+
+    /** Used memory change rate in bytes per second */
+    private long maxRateOfChange = 1;
+
+
+    /**
+     * Parameterize the StoreJanitorImpl.
+     */
+    public void parameterize(Parameters params) throws ParameterException {
+        this.jvm = Runtime.getRuntime();
+        this.minFreeMemory = params.getParameterAsInteger("freememory", 1024 * 1024);
+        this.maxHeapSize = params.getParameterAsInteger("heapsize", 66600000);
+        // Parameter value is in seconds, converted to millis
+        this.threadInterval = params.getParameterAsInteger("cleanupthreadinterval", 10) * 1000;
+        this.adaptiveThreadInterval = params.getParameterAsBoolean("adaptivethreadinterval", false);
+        this.priority = params.getParameterAsInteger("threadpriority", Thread.currentThread().getPriority());
+        int percent = params.getParameterAsInteger("percent_to_free", 10);
+        this.invokeGC = params.getParameterAsBoolean("invokegc", this.invokeGC);
+
+        if (getMinFreeMemory() < 1) {
+            throw new ParameterException("StoreJanitorImpl freememory parameter has to be greater then 1");
+        }
+        if (getMaxHeapSize() < 1) {
+            throw new ParameterException("StoreJanitorImpl heapsize parameter has to be greater then 1");
+        }
+        if (getThreadInterval() < 1) {
+            throw new ParameterException("StoreJanitorImpl cleanupthreadinterval parameter has to be greater then 1");
+        }
+        if (getPriority() < 1 || getPriority() > 10) {
+            throw new ParameterException("StoreJanitorImpl threadpriority has to be between 1 and 10");
+        }
+        if (percent > 100 && percent < 1) {
+            throw new ParameterException("StoreJanitorImpl percent_to_free, has to be between 1 and 100");
+        }
+
+        this.fraction = percent / 100.0D;
+        this.storelist = new ArrayList();
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("minimum free memory=" + getMinFreeMemory());
+            getLogger().debug("heapsize=" + getMaxHeapSize());
+            getLogger().debug("thread interval=" + getThreadInterval());
+            getLogger().debug("adaptivethreadinterval=" + getAdaptiveThreadInterval());
+            getLogger().debug("priority=" + getPriority());
+            getLogger().debug("percent=" + percent);
+            getLogger().debug("invoke gc=" + this.invokeGC);
+        }
+    }
+
+    public void initialize() throws Exception {
+        doStart();
+    }
+
+    private void doStart() throws Exception {
+        this.doRun = true;
+        Thread checker = new Thread(this);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Intializing checker thread");
+        }
+        checker.setPriority(getPriority());
+        checker.setDaemon(true);
+        checker.setName("checker");
+        checker.start();
+    }
+
+    private void doStop() {
+        this.doRun = false;
+    }
+
+    public void dispose() {
+        doStop();
+    }
+
+    /**
+     * The "checker" thread loop.
+     */
+    public void run() {
+        this.inUse = memoryInUse();
+        while (this.doRun) {
+            checkMemory();
+
+            // Sleep
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Sleeping for " + this.interval + "ms");
+            }
+            try {
+                Thread.sleep(this.interval);
+            } catch (InterruptedException ignore) {
+            }
+
+            // Ignore change in memory during the first run (startup)
+            if (this.firstRun) {
+                this.firstRun = false;
+                this.inUse = memoryInUse();
+            }
+        }
+    }
+
+    /**
+     * The "checker" thread checks if memory is running low in the jvm.
+     */
+    protected void checkMemory() {
+        if (getAdaptiveThreadInterval()) {
+            // Monitor the rate of change of heap in use.
+            long change = memoryInUse() - inUse;
+            long rateOfChange = longDiv(change * 1000, interval); // bps.
+            if (maxRateOfChange < rateOfChange) {
+                maxRateOfChange = (maxRateOfChange + rateOfChange) / 2;
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Waking after " + interval + "ms, in use change "
+                                  + change + "b to " + memoryInUse() + "b, rate "
+                                  + rateOfChange + "b/sec, max rate " + maxRateOfChange + "b/sec");
+            }
+        }
+
+        // Amount of memory used is greater than heapsize
+        if (memoryLow()) {
+            if (this.invokeGC) {
+                freePhysicalMemory();
+            }
+
+            synchronized (this) {
+                if (!this.invokeGC
+                        || (memoryLow() && getStoreList().size() > 0)) {
+
+                    freeMemory();
+                    setIndex(getIndex() + 1);
+                }
+            }
+        }
+
+        if (getAdaptiveThreadInterval()) {
+            // Calculate sleep interval based on the change rate and free memory left
+            interval = minTimeToFill(maxRateOfChange) * 1000 / 2;
+            if (interval > this.threadInterval) {
+                interval = this.threadInterval;
+            } else if (interval < this.minThreadInterval) {
+                interval = this.minThreadInterval;
+            }
+            inUse = memoryInUse();
+        } else {
+            interval = this.threadInterval;
+        }
+    }
+
+    /**
+     * Method to check if memory is running low in the JVM.
+     *
+     * @return true if memory is low
+     */
+    private boolean memoryLow() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("JVM Memory total: " + getJVM().totalMemory()
+                              + ", free: " + getJVM().freeMemory());
+        }
+
+        if ((getJVM().totalMemory() >= getMaxHeapSize())
+                && (getJVM().freeMemory() < getMinFreeMemory())) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Memory is low!");
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Calculate the JVM memory in use now.
+     *
+     * @return memory in use.
+     */
+    protected long memoryInUse() {
+        return jvm.totalMemory() - jvm.freeMemory();
+    }
+
+    /**
+     * Calculate amount of time needed to fill all free memory with given
+     * fill rate.
+     *
+     * @param rate memory fill rate in time per bytes
+     * @return amount of time to fill all the memory with given fill rate
+     */
+    private long minTimeToFill(long rate) {
+        return longDiv(jvm.freeMemory(), rate);
+    }
+
+    private long longDiv(long top, long bottom) {
+        try {
+            return top / bottom;
+        } catch (Exception e) {
+            return top > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
+        }
+    }
+
+    /**
+     * This method register the stores
+     *
+     * @param store the store to be registered
+     */
+    public synchronized void register(Store store) {
+        getStoreList().add(store);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Registered store instance " + store + ". Stores now: "
+                              + getStoreList().size());
+        }
+    }
+
+    /**
+     * This method unregister the stores
+     *
+     * @param store the store to be unregistered
+     */
+    public synchronized void unregister(Store store) {
+        getStoreList().remove(store);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Unregistered store instance " + store + ". Stores now: "
+                              + getStoreList().size());
+        }
+    }
+
+    /**
+     * This method return a java.util.Iterator of every registered stores
+     *
+     * <i>The iterators returned is fail-fast: if list is structurally
+     * modified at any time after the iterator is created, in any way, the
+     * iterator will throw a ConcurrentModificationException.  Thus, in the
+     * face of concurrent modification, the iterator fails quickly and
+     * cleanly, rather than risking arbitrary, non-deterministic behavior at
+     * an undetermined time in the future.</i>
+     *
+     * @return a java.util.Iterator
+     */
+    public Iterator iterator() {
+        return getStoreList().iterator();
+    }
+
+    /**
+     * Round Robin alghorithm for freeing the registered caches.
+     */
+    private void freeMemory() {
+        // TODO: Alternative to RR might be to free same fraction from every storage.
+        try {
+            // Determine the store.
+            if (getIndex() < getStoreList().size()) {
+                if (getIndex() == -1) {
+                    setIndex(0);
+                }
+            } else {
+                // Store list changed (one or more store has been removed).
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Restarting from the beginning");
+                }
+                setIndex(0);
+            }
+
+            // Delete proportionate elements out of the store as configured.
+            Store store = (Store)getStoreList().get(getIndex());
+            int limit = calcToFree(store);
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Freeing " + limit + " items from store #" + getIndex());
+            }
+
+            for (int i = 0; i < limit; i++) {
+                try {
+                    store.free();
+                } catch (OutOfMemoryError e) {
+                    getLogger().error("OutOfMemoryError in freeMemory()");
+                }
+            }
+        } catch (Exception e) {
+            getLogger().error("Error in freeMemory()", e);
+        } catch (OutOfMemoryError e) {
+            getLogger().error("OutOfMemoryError in freeMemory()");
+        }
+    }
+
+    /**
+     * This method claculates the number of Elements to be freememory
+     * out of the Cache.
+     *
+     * @param store the Store which was selected as victim
+     * @return number of elements to be removed!
+     */
+    private int calcToFree(Store store) {
+        int cnt = store.size();
+        if (cnt < 0) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Unknown size of the store: " + store);
+            }
+            return 0;
+        }
+
+        final int res = (int) (cnt * fraction);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Calculating size for store " + store + " with size " + cnt + ": " + res);
+        }
+        return res;
+    }
+
+    /**
+     * This method forces the garbage collector
+     */
+    private void freePhysicalMemory() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Invoking GC. Memory total: "
+                              + getJVM().totalMemory() + ", free: "
+                              + getJVM().freeMemory());
+        }
+
+        getJVM().runFinalization();
+        getJVM().gc();
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("GC complete. Memory total: "
+                              + getJVM().totalMemory() + ", free: "
+                              + getJVM().freeMemory());
+        }
+    }
+
+
+    private int getMinFreeMemory() {
+        return this.minFreeMemory;
+    }
+
+    private int getMaxHeapSize() {
+        return this.maxHeapSize;
+    }
+
+    private int getPriority() {
+        return this.priority;
+    }
+
+    private int getThreadInterval() {
+        return this.threadInterval;
+    }
+
+    private boolean getAdaptiveThreadInterval() {
+        return this.adaptiveThreadInterval;
+    }
+
+    private Runtime getJVM() {
+        return this.jvm;
+    }
+
+    private ArrayList getStoreList() {
+        return this.storelist;
+    }
+
+    private void setIndex(int _index) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Setting index=" + _index);
+        }
+        this.index = _index;
+    }
+
+    private int getIndex() {
+        return this.index;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/ehcache.xml
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/ehcache.xml?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/ehcache.xml (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/ehcache.xml Thu Nov  3 05:41:06 2005
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<ehcache>
+
+    <!-- Sets the path to the directory where cache .data files are created.
+
+         If the path is a Java System Property it is replaced by
+         its value in the running VM.
+
+         The following properties are translated:
+         user.home - User's home directory
+         user.dir - User's current working directory
+         java.io.tmpdir - Default temp file path -->
+    <diskStore path="java.io.tmpdir"/>
+
+    <!--Default Cache configuration. These will be applied to caches programmatically created through
+        the CacheManager.
+
+        The following attributes are required:
+
+        maxElementsInMemory            - Sets the maximum number of objects that will be created in memory
+        eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the
+                                         element is never expired.
+        overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache
+                                         has reached the maxInMemory limit.
+
+        The following attributes are optional:
+        timeToIdleSeconds              - Sets the time to idle for an element before it expires.
+                                         i.e. The maximum amount of time between accesses before an element expires
+                                         Is only used if the element is not eternal.
+                                         Optional attribute. A value of 0 means that an Element can idle for infinity.
+                                         The default value is 0.
+        timeToLiveSeconds              - Sets the time to live for an element before it expires.
+                                         i.e. The maximum time between creation time and when an element expires.
+                                         Is only used if the element is not eternal.
+                                         Optional attribute. A value of 0 means that and Element can live for infinity.
+                                         The default value is 0.
+        diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.
+                                         The default value is false.
+        diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
+                                         is 120 seconds.
+        -->
+
+    <defaultCache
+        maxElementsInMemory="10000"
+        eternal="true"
+        timeToIdleSeconds="0"
+        timeToLiveSeconds="0"
+        overflowToDisk="true"
+        diskPersistent="true"
+        diskExpiryThreadIntervalSeconds="120"
+        />
+
+</ehcache>

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/store/impl/ehcache.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/BoundedQueue.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/BoundedQueue.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/BoundedQueue.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/BoundedQueue.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,65 @@
+/*
+ * 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 current size of queue.
+     */
+    public int getQueueSize() {
+        return usedSlots_;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/BoundedQueue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/ChannelWrapper.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/ChannelWrapper.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/ChannelWrapper.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/ChannelWrapper.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,84 @@
+/*
+ * 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: ChannelWrapper.java 321157 2005-10-14 17:21:29Z cziegeler $
+ */
+public class ChannelWrapper
+    implements Channel {
+
+    //~ Instance fields --------------------------------------------------------
+
+    /** The wrapped Channel */
+    private Channel channel;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param channel DOCUMENT ME!
+     */
+    public void setChannel( final Channel channel ) {
+        this.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 channel.offer( obj, timeout );
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Channel#peek()
+     */
+    public Object peek() {
+        return channel.peek();
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Takable#poll(long)
+     */
+    public Object poll( final long timeout )
+    throws InterruptedException {
+        return channel.poll( timeout );
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Puttable#put(java.lang.Object)
+     */
+    public void put( final Object obj )
+    throws InterruptedException {
+        channel.put( obj );
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Takable#take()
+     */
+    public Object take()  throws InterruptedException {
+        return channel.take();
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/ChannelWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,774 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Startable;
+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 org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * 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;daemon&gt;false&lt;/daemon&gt;
+ *       &lt;queue-size&gt;-1&lt;/queue-size&gt;
+ *       &lt;max-pool-size&gt;-1&lt;/max-pool-size&gt;
+ *       &lt;min-pool-size&gt;2&lt;/min-pool-size&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>
+ *
+ * <p>
+ * Have a look at
+ * http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html,
+ * {@link EDU.oswego.cs.dl.util.concurrent.PooledExecutor} or the cocoon.xconf
+ * file for more information.
+ * </p>
+ *
+ * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a>
+ * @version $Id: DefaultRunnableManager.java 326062 2005-10-18 09:31:53Z sylvain $
+ */
+public class DefaultRunnableManager
+    extends AbstractLogEnabled
+    implements RunnableManager,
+               Configurable,
+               Disposable,
+               Startable,
+               Runnable,
+               ThreadSafe {
+    
+    //~ 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 daemon mode */
+    public static final boolean DEFAULT_DAEMON_MODE = false;
+
+    /** The default keep alive time */
+    public static final long DEFAULT_KEEP_ALIVE_TIME = 60000L;
+
+    /** 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 --------------------------------------------------------
+
+    /**
+     * Sorted set of <code>ExecutionInfo</code> instances, based on their next
+     * execution time.
+     */
+    protected SortedSet commandStack = new TreeSet();
+
+    /** The managed thread pools */
+    final Map pools = new HashMap();
+
+    /** The configured default ThreadFactory class instance */
+    private Class defaultThreadFactoryClass;
+
+    /** Keep us running? */
+    private boolean keepRunning = false;
+
+    //~ 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 {
+            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.getChild( "thread-pools" ).getChildren( "thread-pool" );
+
+        for( int i = 0; i < threadpools.length; i++ ) {
+            final DefaultThreadPool pool = configThreadPool( threadpools[ i ] );
+        }
+
+        // Check if a "default" pool has been created
+        final ThreadPool defaultThreadPool =
+            (ThreadPool)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_DAEMON_MODE, 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 isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @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
+     *
+     * @throws IllegalArgumentException If the pool already exists
+     */
+    public void createPool( final String name,
+                            final int queueSize,
+                            final int maxPoolSize,
+                            final int minPoolSize,
+                            final int priority,
+                            final boolean isDaemon,
+                            final long keepAliveTime,
+                            final String blockPolicy,
+                            final boolean shutdownGraceful,
+                            final int shutdownWaitTime ) {
+        if( null != pools.get( name ) ) {
+            throw new IllegalArgumentException( "ThreadPool \"" + name +
+                                                "\" already exists" );
+        }
+
+        createPool( new DefaultThreadPool(  ), name, queueSize, maxPoolSize,
+                    minPoolSize, priority, isDaemon, 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 isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @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 boolean isDaemon,
+                                  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, isDaemon, keepAliveTime, blockPolicy,
+                           shutdownGraceful, shutdownWaitTime );
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Disposing all thread pools" );
+        }
+
+        for( final Iterator i = pools.keySet().iterator(); i.hasNext(); ) {
+            final String poolName = (String)i.next();
+            final DefaultThreadPool pool =
+                (DefaultThreadPool)pools.get( poolName );
+
+            if( getLogger().isDebugEnabled(  ) ) {
+                getLogger().debug( "Disposing thread pool " +
+                                     pool.getName() );
+            }
+
+            pool.shutdown();
+
+            if( getLogger().isDebugEnabled(  ) ) {
+                getLogger().debug( "Thread pool " + pool.getName() +
+                                     " disposed" );
+            }
+        }
+
+        try {
+            pools.clear();
+        } catch( final Throwable t ) {
+            getLogger().error( "Cannot dispose", t );
+        }
+    }
+
+    /**
+     * 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
+     *
+     * @throws IllegalArgumentException DOCUMENT ME!
+     */
+    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)pools.get( threadPoolName );
+
+        if( null == pool ) {
+            getLogger().warn( "ThreadPool \"" + threadPoolName +
+                              "\" is not known. Will use ThreadPool \"" +
+                              DEFAULT_THREADPOOL_NAME + "\"" );
+            pool = (ThreadPool)pools.get( DEFAULT_THREADPOOL_NAME );
+        }
+
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Command entered: " + command.toString() +
+                               ", pool=" + pool.getName() + ", delay=" +
+                               delay + ", interval=" + interval );
+        }
+
+        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 );
+    }
+
+    /**
+     * Remove a <code>Runnable</code> from the command stack
+     *
+     * @param command The <code>Runnable</code> to be removed
+     */
+    public void remove( Runnable command ) {
+        synchronized( commandStack ) {
+            for( final Iterator i = commandStack.iterator(); i.hasNext(); ) {
+                final ExecutionInfo info = (ExecutionInfo)i.next();
+
+                if( info.m_command == command ) {
+                    i.remove();
+                    commandStack.notifyAll();
+
+                    return;
+                }
+            }
+        }
+
+        getLogger().warn( "Could not find command " + command +
+                          " for removal" );
+    }
+
+    /**
+     * The heart of the command manager
+     */
+    public void run()
+    {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Entering loop" );
+        }
+
+        while( keepRunning ) {
+            synchronized( commandStack ) {
+                try {
+                    if( commandStack.size(  ) > 0 ) {
+                        final ExecutionInfo info =
+                            (ExecutionInfo)commandStack.first();
+                        final long delay =
+                            info.m_nextRun - System.currentTimeMillis( );
+
+                        if( delay > 0 ) {
+                            commandStack.wait( delay );
+                        }
+                    } else {
+                        if( getLogger().isDebugEnabled() ) {
+                            getLogger().debug( "No commands available. Will just wait for one" );
+                        }
+
+                        commandStack.wait();
+                    }
+                } catch( final InterruptedException ie ) {
+                    if( getLogger().isDebugEnabled() ) {
+                        getLogger().debug( "I've been interrupted" );
+                    }
+                }
+
+                if( keepRunning ) {
+                    if( commandStack.size() > 0 ) {
+                        final ExecutionInfo info =
+                            (ExecutionInfo)commandStack.first();
+                        final long delay =
+                            info.m_nextRun - System.currentTimeMillis();
+
+                        if( delay < 0 ) {
+                            info.execute();
+                        }
+                    }
+                }
+            }
+        }
+
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Exiting loop" );
+        }
+    }
+    
+    /**
+     * Start the managing thread
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    public void start() throws Exception {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Starting the heart" );
+        }
+
+        keepRunning = true;
+        ( (ThreadPool) pools.get( DEFAULT_THREADPOOL_NAME ) ).execute( this );
+    }
+
+    /**
+     * Stop the managing thread
+     */
+    public void stop( ) {
+        keepRunning = false;
+
+        synchronized( commandStack ) {
+            commandStack.notifyAll();
+        }
+    }
+
+    /**
+     * 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 {
+            getLogger().warn( "Unknown thread priority \"" + priority +
+                              "\". Set to \"NORM\"." );
+
+            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 > 0 ) && ( minPoolSize < DEFAULT_MIN_POOL_SIZE ) ) ) {
+            minPoolSize = DEFAULT_MIN_POOL_SIZE;
+        }
+
+        final String priority =
+            config.getChild( "priority" ).getValue( DEFAULT_THREAD_PRIORITY );
+        final boolean isDaemon =
+            config.getChild( "daemon" ).getValueAsBoolean( DEFAULT_DAEMON_MODE );
+        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 ),
+                           isDaemon, 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 isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @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 boolean isDaemon,
+                                          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)defaultThreadFactoryClass.newInstance(  );
+        } catch( final Exception ex ) {
+            getLogger().warn( "Cannot instantiate a ThreadFactory from class " +
+                              defaultThreadFactoryClass.getName() +
+                              ". Will use a " +
+                              DefaultThreadFactory.class.getName(), ex );
+            factory = new DefaultThreadFactory(  );
+        }
+
+        factory.setPriority( priority );
+        factory.setDaemon( isDaemon );
+        pool.setThreadFactory( factory );
+        pool.setQueue( queueSize );
+        pool.setMaximumPoolSize( ( maxPoolSize < 0 ) ? Integer.MAX_VALUE
+                                 : maxPoolSize );
+
+        if( minPoolSize < 1 ) {
+            getLogger().warn( "min-pool-size < 1 for pool \"" +
+                              name + "\". Set to 1" );
+        }
+
+        pool.setMinimumPoolSize( ( minPoolSize < 1 ) ? 1 : minPoolSize );
+
+        if( keepAliveTime < 0 ) {
+            getLogger().warn( "keep-alive-time-ms < 0 for pool \"" +
+                              name + "\". Set to 1000" );
+        }
+
+        pool.setKeepAliveTime( ( keepAliveTime < 0 ) ? 1000 : keepAliveTime );
+        pool.setBlockPolicy( blockPolicy );
+        pool.setShutdownGraceful( shutdownGraceful );
+        pool.setShutdownWaitTimeMs( shutdownWaitTime );
+
+        synchronized( pools ) {
+            pools.put( name, pool );
+        }
+
+        printPoolInfo( pool );
+        return pool;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pool DOCUMENT ME!
+     */
+    private void printPoolInfo( final DefaultThreadPool pool ) {
+        if( getLogger().isInfoEnabled() ) {
+            if( pool.isQueued() ) {
+                final StringBuffer msg = new StringBuffer();
+                msg.append( "ThreadPool named \"" ).append( pool.getName() );
+                msg.append( "\" created with maximum queue-size=" );
+                msg.append( pool.getMaxQueueSize(  ) );
+                msg.append( ",max-pool-size=" ).append( pool.getMaximumPoolSize() );
+                msg.append( ",min-pool-size=" ).append( pool.getMinimumPoolSize() );
+                msg.append( ",priority=" ).append( pool.getPriority() );
+                msg.append( ",isDaemon=" ).append( ( (ThreadFactory)pool.getThreadFactory() ).isDaemon() );
+                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( ",isDaemon=" ).append( ( (ThreadFactory)pool.getThreadFactory() ).isDaemon() );
+                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() );
+            }
+        }
+    }
+
+    //~ Inner Classes ----------------------------------------------------------
+
+    /**
+     * The $classType$ class ...
+     *
+     * @author <a href="mailto:giacomo.at.apache.org">Giacomo Pati</a>
+     * @version $Id: DefaultRunnableManager.java 326062 2005-10-18 09:31:53Z sylvain $
+     */
+    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( commandStack )
+            {
+                commandStack.add( this );
+                commandStack.notifyAll();
+            }
+            Thread.yield(); // Give others a chance to run
+        }
+
+        //~ Methods ------------------------------------------------------------
+
+        /**
+         * DOCUMENT ME!
+         *
+         * @param other DOCUMENT ME!
+         *
+         * @return DOCUMENT ME!
+         */
+        public int compareTo( final Object other ) {
+            final ExecutionInfo otherInfo = (ExecutionInfo)other;
+            int diff = (int)( m_nextRun - otherInfo.m_nextRun );
+            if (diff == 0) {
+                if (this == other) {
+                    // Same object, return 0.
+                    return 0;
+                } else {
+                    // NOT the same object, MUST return non-0 value.
+                    return System.identityHashCode(this) - System.identityHashCode(other);
+                }
+            }
+            return diff;
+        }
+
+        /**
+         * DOCUMENT ME!
+         */
+        void execute() {
+            if( m_logger.isDebugEnabled() ) {
+                m_logger.debug( "Executing command " + m_command + " in pool \"" +
+                                 m_pool.getName() + "\", schedule with interval=" + m_interval );
+            }
+
+            synchronized( commandStack ) {
+                commandStack.remove( this );
+                if( m_interval > 0 ) {
+                    m_nextRun = System.currentTimeMillis() + m_interval;
+                    commandStack.add( this );
+                }
+            }
+
+            try {
+                m_pool.execute( m_command );
+            } catch( final InterruptedException ie ) {
+                if( m_logger.isDebugEnabled() ) {
+                    m_logger.debug( "Interrupted executing command + " + m_command );
+                }
+            } catch( final Throwable t ) {
+                m_logger.error( "Exception executing command " + m_command, t );
+            }
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,93 @@
+/*
+ * 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: DefaultThreadFactory.java 321157 2005-10-14 17:21:29Z cziegeler $
+ */
+public class DefaultThreadFactory
+    implements ThreadFactory, EDU.oswego.cs.dl.util.concurrent.ThreadFactory {
+    //~ Instance fields --------------------------------------------------------
+
+    /** The daemon mode */
+    private boolean m_isDaemon = false;
+
+    /** The priority of newly created Threads */
+    private int m_priority = Thread.NORM_PRIORITY;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * Set the isDaemon property
+     *
+     * @param isDaemon Whether or not new <code>Thread</code> should run as
+     *        daemons.
+     */
+    public void setDaemon( boolean isDaemon ) {
+        m_isDaemon = isDaemon;
+    }
+
+    /**
+     * Get the isDaemon property
+     *
+     * @return Whether or not new <code>Thread</code> will run as daemons.
+     */
+    public boolean isDaemon() {
+        return m_isDaemon;
+    }
+
+    /**
+     * 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}
+     */
+    public void setPriority( final int priority ) {
+        if( ( Thread.MAX_PRIORITY == priority ) ||
+            ( Thread.MIN_PRIORITY == priority ) ||
+            ( Thread.NORM_PRIORITY == priority ) ) {
+            m_priority = priority;
+        }
+    }
+
+    /**
+     * Get the priority newly created <code>Thread</code>s will have
+     *
+     * @return One of {@link Thread#MIN_PRIORITY}, {@link
+     *         Thread#NORM_PRIORITY}, {@link Thread#MAX_PRIORITY}
+     */
+    public int getPriority() {
+        return m_priority;
+    }
+
+    /**
+     * Create a new Thread for Runnable
+     *
+     * @param command The {@link Runnable}
+     *
+     * @return A new Thread instance
+     */
+    public Thread newThread( final Runnable command ) {
+        final Thread thread = new Thread( command );
+        thread.setPriority( m_priority );
+        thread.setDaemon( m_isDaemon );
+
+        return thread;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,318 @@
+/*
+ * 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 321157 2005-10-14 17:21:29Z cziegeler $
+ */
+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 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 maximum size of the queue (0 if isQueued() == false)
+     *
+     * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
+     */
+    public int getMaxQueueSize() {
+        return ( ( m_queueSize < 0 ) ? Integer.MAX_VALUE : m_queueSize );
+    }
+
+    /**
+     * 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 ((ThreadFactory)super.getThreadFactory()).getPriority();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return current size of the 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;
+    }
+
+    /**
+     * Execute a command
+     *
+     * @param command The {@link Runnable} to execute
+     *
+     * @throws InterruptedException In case of interruption
+     */
+    public void execute( Runnable command ) throws InterruptedException {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Executing Command: " + command.toString() +
+                                 ",pool=" + getName() );
+        }
+
+        super.execute( command );
+    }
+
+    /**
+     * @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 ) {
+        m_blockPolicy = 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;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/LinkedQueue.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/LinkedQueue.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/LinkedQueue.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/LinkedQueue.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,43 @@
+/*
+ * 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 {
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see org.apache.cocoon.components.thread.Queue#getQueueSize()
+     */
+    public int getQueueSize() {
+        return -1;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/LinkedQueue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/Queue.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/Queue.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/Queue.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/Queue.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,38 @@
+/*
+ * 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: Queue.java 321157 2005-10-14 17:21:29Z cziegeler $
+ *
+ * @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 current size of queue. If the size of the queue is not
+     *         maintained by an implementation -1 should be returned.
+     */
+    int getQueueSize();
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/Queue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/RunnableManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/RunnableManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/RunnableManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/RunnableManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,162 @@
+/*
+ * 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: RunnableManager.java 321157 2005-10-14 17:21:29Z cziegeler $
+ */
+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 isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @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,
+                     final boolean isDaemon,
+                     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 isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @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,
+                           final boolean isDaemon,
+                           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 );
+
+    /**
+     * Remove a {@link Runnable} from the execution stack
+     *
+     * @param command The command to be removed
+     */
+    void remove( Runnable command );
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/RunnableManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/SynchronousChannel.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/SynchronousChannel.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/SynchronousChannel.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/SynchronousChannel.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,54 @@
+/*
+ * 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 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;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/components/thread/SynchronousChannel.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message