001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.connector.work.pool;
019    
020    import java.util.concurrent.LinkedBlockingQueue;
021    import java.util.concurrent.ThreadPoolExecutor;
022    import java.util.concurrent.TimeUnit;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    
027    /**
028     * Based class for WorkExecutorPool. Sub-classes define the synchronization
029     * policy (should the call block until the end of the work; or when it starts
030     * et cetera).
031     *
032     * @version $Rev: 585608 $ $Date: 2007-10-17 19:56:54 +0200 (Wed, 17 Oct 2007) $
033     */
034    public class WorkExecutorPoolImpl implements WorkExecutorPool {
035    
036        /**
037         * A timed out pooled executor.
038         */
039        private ThreadPoolExecutor pooledExecutor;
040        private static Log log = LogFactory.getLog(WorkExecutorPoolImpl.class);
041    
042        /**
043         * Creates a pool with the specified minimum and maximum sizes. The Channel
044         * used to enqueue the submitted Work instances is queueless synchronous
045         * one.
046         *
047         * @param maxSize Maximum size of the work executor pool.
048         */
049        public WorkExecutorPoolImpl(int maxSize) {
050            pooledExecutor = new ThreadPoolExecutor(1, maxSize, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
051            /*
052            FIXME: How to do this with concurrent.util ?
053            pooledExecutor.waitWhenBlocked();
054            */
055        }
056        
057        /**
058         * Execute the specified Work.
059         *
060         * @param work Work to be executed.
061         */
062        public void execute(Runnable work) {
063            if(pooledExecutor.getPoolSize() == pooledExecutor.getMaximumPoolSize()) {
064                log.warn("Maximum Pool size has been exceeded.  Current Pool Size = "+pooledExecutor.getMaximumPoolSize());
065            }
066    
067            pooledExecutor.execute(work);
068        }
069    
070        /**
071         * Gets the size of this pool.
072         */
073        public int getPoolSize() {
074            return pooledExecutor.getPoolSize();
075        }
076    
077        /**
078         * Gets the maximum size of this pool.
079         */
080        public int getMaximumPoolSize() {
081            return pooledExecutor.getMaximumPoolSize();
082        }
083    
084        /**
085         * Sets the maximum size of this pool.
086         * @param maxSize New maximum size of this pool.
087         */
088        public void setMaximumPoolSize(int maxSize) {
089            pooledExecutor.setMaximumPoolSize(maxSize);
090        }
091    
092        public WorkExecutorPool start() {
093            throw new IllegalStateException("This pooled executor is already started");
094        }
095    
096        /**
097         * Stops this pool. Prior to stop this pool, all the enqueued Work instances
098         * are processed. This is an orderly shutdown.
099         */
100        public WorkExecutorPool stop() {
101            int maxSize = getMaximumPoolSize();
102            pooledExecutor.shutdown();
103            return new NullWorkExecutorPool(maxSize);
104        }
105    
106    }