### Eclipse Workspace Patch 1.0 #P tomcat-8.0.x diff --git java/org/apache/tomcat/util/threads/StopPooledThreadException.java java/org/apache/tomcat/util/threads/StopPooledThreadException.java new file mode 100644 index 0000000..fcee34a --- /dev/null +++ java/org/apache/tomcat/util/threads/StopPooledThreadException.java @@ -0,0 +1,31 @@ +/* + * 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; + + +/** + * A custom {@link RuntimeException} thrown by the {@link ThreadPoolExecutor} + * to signal that the thread should be disposed of. + */ +public class StopPooledThreadException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public StopPooledThreadException(String msg) { + super(msg); + } +} diff --git java/org/apache/tomcat/util/threads/TaskThread.java java/org/apache/tomcat/util/threads/TaskThread.java index c7fb265..5a7e0f3 100644 --- java/org/apache/tomcat/util/threads/TaskThread.java +++ java/org/apache/tomcat/util/threads/TaskThread.java @@ -16,22 +16,26 @@ */ package org.apache.tomcat.util.threads; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + /** * A Thread implementation that records the time at which it was created. * */ public class TaskThread extends Thread { + private static final Log log = LogFactory.getLog(TaskThread.class); private final long creationTime; public TaskThread(ThreadGroup group, Runnable target, String name) { - super(group, target, name); + super(group, new WrappingRunnable(target), name); this.creationTime = System.currentTimeMillis(); } public TaskThread(ThreadGroup group, Runnable target, String name, long stackSize) { - super(group, target, name, stackSize); + super(group, new WrappingRunnable(target), name, stackSize); this.creationTime = System.currentTimeMillis(); } @@ -42,4 +46,26 @@ return creationTime; } + /** + * Wraps a {@link Runnable} to swallow any {@link StopPooledThreadException} + * instead of letting it go and potentially trigger a break in a debugger. + */ + private static class WrappingRunnable implements Runnable { + private Runnable wrappedRunnable; + WrappingRunnable(Runnable wrappedRunnable) { + this.wrappedRunnable = wrappedRunnable; + } + @Override + public void run() { + try { + wrappedRunnable.run(); + } catch(StopPooledThreadException exc) { + //expected : we just swallow the exception to avoid disturbing + //debuggers like eclipse's + log.debug("Thread exiting on purpose", exc); + } + } + + } + } diff --git java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java index 9cd4cc2..1dbc930 100644 --- java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java +++ java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java @@ -16,7 +16,6 @@ */ package org.apache.tomcat.util.threads; -import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.BlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionHandler; @@ -25,8 +24,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import org.apache.juli.logging.Log; -import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; /** @@ -42,8 +39,6 @@ */ protected static final StringManager sm = StringManager .getManager("org.apache.tomcat.util.threads.res"); - - private static final Log log = LogFactory.getLog(ThreadPoolExecutor.class); /** * The number of tasks submitted but not yet finished. This includes tasks @@ -116,16 +111,7 @@ "threadPoolExecutor.threadStoppedToAvoidPotentialLeak", Thread.currentThread().getName()); - Thread.currentThread().setUncaughtExceptionHandler( - new UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, - Throwable e) { - // yes, swallow the exception - log.debug(msg); - } - }); - throw new RuntimeException(msg); + throw new StopPooledThreadException(msg); } } }