/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.tomcat.util.threads;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * Same as a java.util.concurrent.ThreadPoolExecutor but implements a much more efficient
 * getActiveCount method, to be used to properly handle the work queue
 * @author fhanik
 *
 */
public class ThreadPoolExecutor extends java.util.concurrent.ThreadPoolExecutor {
    
    final AtomicInteger activeCount = new AtomicInteger(0);
    
    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
            RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        activeCount.decrementAndGet();
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        activeCount.incrementAndGet();
    }

    @Override
    public int getActiveCount() {
        return activeCount.get();
    }
    
    public void execute(Runnable command, long timeout, TimeUnit unit) {
        
    }
    
    

    
    
}

@@ -882,16 +882,72 @@
 gQueue;%0A
+import java.util.concurrent.RejectedExecutionException;%0A
 import j
@@ -1288,16 +1288,162 @@
 k queue%0A
+ * If a RejectedExecutionHandler is not specified a default one will be configured%0A * and that one will always throw a RejectedExecutionException%0A
  * @auth
@@ -2465,16 +2465,37 @@
 dFactory
+, new RejectHandler()
 );%0A    %7D
@@ -2712,16 +2712,37 @@
 orkQueue
+, new RejectHandler()
 );%0A    %7D
@@ -3080,101 +3080,1904 @@
     
-public void execute(Runnable command, long timeout, TimeUnit unit) %7B%0A        %0A    %7D%0A    %0A    
+/**%0A     * %7B@inheritDoc%7D%0A     */%0A    @Override%0A    public void execute(Runnable command) %7B%0A        execute(command,0,TimeUnit.MILLISECONDS);%0A    %7D%0A    %0A    /**%0A     * Executes the given command at some time in the future.  The command%0A     * may execute in a new thread, in a pooled thread, or in the calling%0A     * thread, at the discretion of the %3Ctt%3EExecutor%3C/tt%3E implementation.%0A     * If no threads are available, it will be added to the work queue.%0A     * If the work queue is full, the system will wait for the specified %0A     * time and it throw a RejectedExecutionException if the queue is still full after that.%0A     *%0A     * @param command the runnable task%0A     * @throws RejectedExecutionException if this task cannot be%0A     * accepted for execution - the queue is full%0A     * @throws NullPointerException if command or unit is null%0A     */%0A    public void execute(Runnable command, long timeout, TimeUnit unit) %7B%0A        try %7B%0A            super.execute(command);%0A        %7D catch (RejectedExecutionException rx) %7B%0A            if (super.getQueue() instanceof TaskQueue) %7B%0A                TaskQueue queue = (TaskQueue)super.getQueue();%0A                try %7B%0A                    if (!queue.force(command, timeout, unit)) %7B%0A                        throw new RejectedExecutionException(%22Queue capacity is full.%22);%0A                    %7D%0A                %7D catch (InterruptedException x) %7B%0A                    Thread.currentThread().interrupted();%0A                    throw new RejectedExecutionException(x);%0A                %7D%0A            %7D else %7B%0A                throw rx;%0A            %7D%0A            %0A        %7D%0A    %7D%0A    %0A    static class RejectHandler implements java.util.concurrent.RejectedExecutionHandler %7B%0A        public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor executor) %7B%0A            throw new RejectedExecutionException();%0A        %7D%0A        %0A    %7D
 %0A%0A  

Implement an execution that adds the task to the queue if rejected, and allow to try to add for a specified time