/*
 * Copyright 2002 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 4680160
 * @summary The deprecated Thread.stop exposes un-checked JNI calls
 *          that result in crashes when NULL is passed into subsequent
 *          JNI calls.
 */

import java.net.*;
import java.io.IOException;

public class ThreadStop {

    static class Server implements Runnable {

        ServerSocket ss;

        Server() throws IOException {
            ss = new ServerSocket(0);
        }

        public int localPort() {
            return ss.getLocalPort();
        }


        public void run() {
            try {
                Socket s = ss.accept();
            } catch (IOException ioe) {
            } catch (ThreadDeath x) {
            } finally {
                try {
                    ss.close();
                } catch (IOException x) { }
            }
        }
    }

    public static void main(String args[]) throws Exception {

        // start a server
        Server svr = new Server();
        Thread thr = new Thread(svr);
        thr.start();

        // give server time to block in ServerSocket.accept()
        Thread.currentThread().sleep(2000);

        // "stop" the thread
        thr.stop();

        // give thread time to stop
        Thread.currentThread().sleep(2000);

        // it's platform specific if Thread.stop interrupts the
        // thread - on Linux/Windows most likely that thread is
        // still in accept() so we connect to server which causes
        // it to unblock and do JNI-stuff with a pending exception

        try {
            Socket s = new Socket("localhost", svr.localPort());
        } catch (IOException ioe) { }

    }

}
