133 lines
4.1 KiB
Java
133 lines
4.1 KiB
Java
/*
|
|
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
* have any questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 4519200
|
|
* @summary Confirm a Thread.stop before start complies with the spec
|
|
* @author Pete Soper
|
|
*
|
|
* Confirm that a thread that had its stop method invoked before start
|
|
* does properly terminate with expected exception behavior. NOTE that
|
|
* arbitrary application threads could return from their run methods faster
|
|
* than the VM can throw an async exception.
|
|
*/
|
|
public class StopBeforeStart {
|
|
|
|
private static final int JOIN_TIMEOUT=10000;
|
|
|
|
private class MyThrowable extends Throwable {
|
|
}
|
|
|
|
private class Catcher implements Thread.UncaughtExceptionHandler {
|
|
private boolean nullaryStop;
|
|
private Throwable theThrowable;
|
|
private Throwable expectedThrowable;
|
|
private boolean exceptionThrown;
|
|
|
|
Catcher(boolean nullaryStop) {
|
|
this.nullaryStop = nullaryStop;
|
|
if (!nullaryStop) {
|
|
expectedThrowable = new MyThrowable();
|
|
}
|
|
}
|
|
|
|
public void uncaughtException(Thread t, Throwable th) {
|
|
exceptionThrown = true;
|
|
theThrowable = th;
|
|
}
|
|
|
|
void check(String label) throws Throwable {
|
|
if (!exceptionThrown) {
|
|
throw new RuntimeException(label +
|
|
" test:" + " missing uncaught exception");
|
|
}
|
|
|
|
if (nullaryStop) {
|
|
if (! (theThrowable instanceof ThreadDeath)) {
|
|
throw new RuntimeException(label +
|
|
" test:" + " expected ThreadDeath in uncaught handler");
|
|
}
|
|
} else if (theThrowable != expectedThrowable) {
|
|
throw new RuntimeException(label +
|
|
" test:" + " wrong Throwable in uncaught handler");
|
|
}
|
|
}
|
|
}
|
|
|
|
private class MyRunnable implements Runnable {
|
|
public void run() {
|
|
while(true)
|
|
;
|
|
}
|
|
}
|
|
|
|
private class MyThread extends Thread {
|
|
public void run() {
|
|
while(true)
|
|
;
|
|
}
|
|
}
|
|
|
|
|
|
public static void main(String args[]) throws Throwable {
|
|
(new StopBeforeStart()).doit();
|
|
System.out.println("Test passed");
|
|
}
|
|
|
|
private void doit() throws Throwable {
|
|
|
|
runit(false, new Thread(new MyRunnable()),"Thread");
|
|
runit(true, new Thread(new MyRunnable()),"Thread");
|
|
runit(false, new MyThread(),"Runnable");
|
|
runit(true, new MyThread(),"Runnable");
|
|
}
|
|
|
|
private void runit(boolean nullaryStop, Thread thread,
|
|
String type) throws Throwable {
|
|
|
|
Catcher c = new Catcher(nullaryStop);
|
|
thread.setUncaughtExceptionHandler(c);
|
|
|
|
if (nullaryStop) {
|
|
thread.stop();
|
|
} else {
|
|
thread.stop(c.expectedThrowable);
|
|
}
|
|
|
|
thread.start();
|
|
thread.join(JOIN_TIMEOUT);
|
|
|
|
if (thread.getState() != Thread.State.TERMINATED) {
|
|
|
|
thread.stop();
|
|
|
|
// Under high load this could be a false positive
|
|
throw new RuntimeException(type +
|
|
" test:" + " app thread did not terminate");
|
|
}
|
|
|
|
c.check(type);
|
|
}
|
|
}
|