blob: a0ae20aad863375a4ced031e6b5a0c408a2dc439 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 4519200
27 * @summary Confirm a Thread.stop before start complies with the spec
28 * @author Pete Soper
29 *
30 * Confirm that a thread that had its stop method invoked before start
31 * does properly terminate with expected exception behavior. NOTE that
32 * arbitrary application threads could return from their run methods faster
33 * than the VM can throw an async exception.
34 */
35public class StopBeforeStart {
36
37 private static final int JOIN_TIMEOUT=10000;
38
39 private class MyThrowable extends Throwable {
40 }
41
42 private class Catcher implements Thread.UncaughtExceptionHandler {
43 private boolean nullaryStop;
44 private Throwable theThrowable;
45 private Throwable expectedThrowable;
46 private boolean exceptionThrown;
47
48 Catcher(boolean nullaryStop) {
49 this.nullaryStop = nullaryStop;
50 if (!nullaryStop) {
51 expectedThrowable = new MyThrowable();
52 }
53 }
54
55 public void uncaughtException(Thread t, Throwable th) {
56 exceptionThrown = true;
57 theThrowable = th;
58 }
59
60 void check(String label) throws Throwable {
61 if (!exceptionThrown) {
62 throw new RuntimeException(label +
63 " test:" + " missing uncaught exception");
64 }
65
66 if (nullaryStop) {
67 if (! (theThrowable instanceof ThreadDeath)) {
68 throw new RuntimeException(label +
69 " test:" + " expected ThreadDeath in uncaught handler");
70 }
71 } else if (theThrowable != expectedThrowable) {
72 throw new RuntimeException(label +
73 " test:" + " wrong Throwable in uncaught handler");
74 }
75 }
76 }
77
78 private class MyRunnable implements Runnable {
79 public void run() {
80 while(true)
81 ;
82 }
83 }
84
85 private class MyThread extends Thread {
86 public void run() {
87 while(true)
88 ;
89 }
90 }
91
92
93 public static void main(String args[]) throws Throwable {
94 (new StopBeforeStart()).doit();
95 System.out.println("Test passed");
96 }
97
98 private void doit() throws Throwable {
99
100 runit(false, new Thread(new MyRunnable()),"Thread");
101 runit(true, new Thread(new MyRunnable()),"Thread");
102 runit(false, new MyThread(),"Runnable");
103 runit(true, new MyThread(),"Runnable");
104 }
105
106 private void runit(boolean nullaryStop, Thread thread,
107 String type) throws Throwable {
108
109 Catcher c = new Catcher(nullaryStop);
110 thread.setUncaughtExceptionHandler(c);
111
112 if (nullaryStop) {
113 thread.stop();
114 } else {
115 thread.stop(c.expectedThrowable);
116 }
117
118 thread.start();
119 thread.join(JOIN_TIMEOUT);
120
121 if (thread.getState() != Thread.State.TERMINATED) {
122
123 thread.stop();
124
125 // Under high load this could be a false positive
126 throw new RuntimeException(type +
127 " test:" + " app thread did not terminate");
128 }
129
130 c.check(type);
131 }
132}