View | Details | Raw Unified | Return to bug 56492
Collapse All | Expand All

(-)java/org/apache/tomcat/util/threads/StopPooledThreadException.java (+31 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package org.apache.tomcat.util.threads;
18
19
20
/**
21
 * A custom {@link RuntimeException} thrown by the {@link ThreadPoolExecutor}
22
 * to signal that the thread should be disposed of.
23
 */
24
public class StopPooledThreadException extends RuntimeException {
25
26
    private static final long serialVersionUID = 1L;
27
28
    public StopPooledThreadException(String msg) {
29
        super(msg);
30
    }
31
}
(-)java/org/apache/tomcat/util/threads/TaskThread.java (-2 / +28 lines)
Lines 16-37 Link Here
16
 */
16
 */
17
package org.apache.tomcat.util.threads;
17
package org.apache.tomcat.util.threads;
18
18
19
import org.apache.juli.logging.Log;
20
import org.apache.juli.logging.LogFactory;
21
19
/**
22
/**
20
 * A Thread implementation that records the time at which it was created.
23
 * A Thread implementation that records the time at which it was created.
21
 *
24
 *
22
 */
25
 */
23
public class TaskThread extends Thread {
26
public class TaskThread extends Thread {
24
27
28
    private static final Log log = LogFactory.getLog(TaskThread.class);
25
    private final long creationTime;
29
    private final long creationTime;
26
30
27
    public TaskThread(ThreadGroup group, Runnable target, String name) {
31
    public TaskThread(ThreadGroup group, Runnable target, String name) {
28
        super(group, target, name);
32
        super(group, new WrappingRunnable(target), name);
29
        this.creationTime = System.currentTimeMillis();
33
        this.creationTime = System.currentTimeMillis();
30
    }
34
    }
31
35
32
    public TaskThread(ThreadGroup group, Runnable target, String name,
36
    public TaskThread(ThreadGroup group, Runnable target, String name,
33
            long stackSize) {
37
            long stackSize) {
34
        super(group, target, name, stackSize);
38
        super(group, new WrappingRunnable(target), name, stackSize);
35
        this.creationTime = System.currentTimeMillis();
39
        this.creationTime = System.currentTimeMillis();
36
    }
40
    }
37
41
Lines 42-45 Link Here
42
        return creationTime;
46
        return creationTime;
43
    }
47
    }
44
48
49
    /**
50
     * Wraps a {@link Runnable} to swallow any {@link StopPooledThreadException}
51
     * instead of letting it go and potentially trigger a break in a debugger.
52
     */
53
    private static class WrappingRunnable implements Runnable {
54
        private Runnable wrappedRunnable;
55
        WrappingRunnable(Runnable wrappedRunnable) {
56
            this.wrappedRunnable = wrappedRunnable;
57
        }
58
        @Override
59
        public void run() {
60
            try {
61
                wrappedRunnable.run();
62
            } catch(StopPooledThreadException exc) {
63
                //expected : we just swallow the exception to avoid disturbing
64
                //debuggers like eclipse's
65
                log.debug("Thread exiting on purpose", exc);
66
            }
67
        }
68
69
    }
70
45
}
71
}
(-)java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java (-15 / +1 lines)
Lines 16-22 Link Here
16
 */
16
 */
17
package org.apache.tomcat.util.threads;
17
package org.apache.tomcat.util.threads;
18
18
19
import java.lang.Thread.UncaughtExceptionHandler;
20
import java.util.concurrent.BlockingQueue;
19
import java.util.concurrent.BlockingQueue;
21
import java.util.concurrent.RejectedExecutionException;
20
import java.util.concurrent.RejectedExecutionException;
22
import java.util.concurrent.RejectedExecutionHandler;
21
import java.util.concurrent.RejectedExecutionHandler;
Lines 25-32 Link Here
25
import java.util.concurrent.atomic.AtomicInteger;
24
import java.util.concurrent.atomic.AtomicInteger;
26
import java.util.concurrent.atomic.AtomicLong;
25
import java.util.concurrent.atomic.AtomicLong;
27
26
28
import org.apache.juli.logging.Log;
29
import org.apache.juli.logging.LogFactory;
30
import org.apache.tomcat.util.res.StringManager;
27
import org.apache.tomcat.util.res.StringManager;
31
28
32
/**
29
/**
Lines 42-49 Link Here
42
     */
39
     */
43
    protected static final StringManager sm = StringManager
40
    protected static final StringManager sm = StringManager
44
            .getManager("org.apache.tomcat.util.threads.res");
41
            .getManager("org.apache.tomcat.util.threads.res");
45
46
    private static final Log log = LogFactory.getLog(ThreadPoolExecutor.class);
47
42
48
    /**
43
    /**
49
     * The number of tasks submitted but not yet finished. This includes tasks
44
     * The number of tasks submitted but not yet finished. This includes tasks
Lines 116-131 Link Here
116
                                    "threadPoolExecutor.threadStoppedToAvoidPotentialLeak",
111
                                    "threadPoolExecutor.threadStoppedToAvoidPotentialLeak",
117
                                    Thread.currentThread().getName());
112
                                    Thread.currentThread().getName());
118
113
119
                    Thread.currentThread().setUncaughtExceptionHandler(
114
                    throw new StopPooledThreadException(msg);
120
                            new UncaughtExceptionHandler() {
121
                                @Override
122
                                public void uncaughtException(Thread t,
123
                                        Throwable e) {
124
                                    // yes, swallow the exception
125
                                    log.debug(msg);
126
                                }
127
                            });
128
                    throw new RuntimeException(msg);
129
                }
115
                }
130
            }
116
            }
131
        }
117
        }

Return to bug 56492