/*
 * Copyright 2006 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 6417044
 * @summary Test deadlock in MBeanRegistration.postRegister method
 * @author Eamonn McManus, Daniel Fuchs
 * @run clean PostRegisterDeadlockTest
 * @run build PostRegisterDeadlockTest
 * @run main PostRegisterDeadlockTest
 */

import java.lang.Thread.State;
import java.util.concurrent.*;
import javax.management.*;

public class PostRegisterDeadlockTest {
    public static interface BlibbyMBean {}

    public static class Blibby implements BlibbyMBean, MBeanRegistration {
        public Blibby(MBeanServer mbs, ObjectName otherName) {
            this.mbs = mbs;
            this.otherName = otherName;
        }

        public ObjectName preRegister(MBeanServer mbs, ObjectName on) {
            return on;
        }

        public void preDeregister() {}

        public void postRegister(Boolean done) {
            // If no other MBean was registered
            // do nothing.
            //
            if (otherName == null) return;

            // Check that we can unregister
            // other MBean
            try {
                Thread t = new Thread() {
                    public void run() {
                        try {
                            try {
                                mbs.unregisterMBean(otherName);
                            } catch (InstanceNotFoundException x) {
                                 // Race condition!
                                 System.out.println(otherName+
                                         " was unregistered by main thread.");
                            }
                        } catch (Throwable e) {
                            e.printStackTrace(System.out);
                            fail(e.toString());
                        }
                    }
                };
                t.start();
                t.join(5000L);
                if (t.isAlive()) {
                    if (t.getState().equals(State.BLOCKED))
                        fail("Deadlock detected");
                    else
                        fail("Test not conclusive: "+
                             "Thread is alive but not blocked.");
                }
            } catch (Throwable e) {
                e.printStackTrace(System.out);
                fail(e.toString());
            }
        }

        public void postDeregister() {}

        private final MBeanServer mbs;
        private final ObjectName otherName;
    }

    public static void main(String[] args) throws Exception {
        String previous = null;
        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
        ObjectName on1 = new ObjectName("a:type=Blibby,name=\"1\"");
        ObjectName on2 = new ObjectName("a:type=Blibby,name=\"2\"");


        // Test 1:
        // 1 MBean is registered with on1
        // Another MBean is registered with on1, postRegister(FALSE) is
        // called, and the second MBean attempts to unregister first MBean in
        // postRegister:
        // postRegister starts a thread which unregisters the first MBean:
        // this must not deadlock
        //
        System.out.println("\n****  TEST #1 ****\n");
        System.out.println("Registering Blibby #1 with name: " + on1);
        mbs.registerMBean(new Blibby(mbs, null), on1);
        try {
            System.out.println("Registering Blibby #2 with same name: " + on1);
            mbs.registerMBean(new Blibby(mbs, on1), on1);
        } catch (InstanceAlreadyExistsException x) {
            System.out.println("Received expected exception: " + x);
        }
        if (mbs.isRegistered(on1)) {
            try {
                mbs.unregisterMBean(on1);
                if (failure == null)
                    fail(on1+" should have been unregistered");
            } catch (InstanceNotFoundException x) {
                // Race condition!
                System.out.println(on1+" was unregistered by mbean thread.");
            }
        }  else {
            System.out.println(on1+" was correctly unregistered.");
        }

        if (failure == previous)
            System.out.println("\n****  TEST #1 PASSED ****\n");

        previous = failure;

        // Test 2:
        // 1 MBean is registered with on1
        // Another MBean is registered with on2, postRegister(TRUE) is
        // called, and the second MBean attempts to unregister first MBean in
        // postRegister:
        // postRegister starts a thread which unregisters the first MBean:
        // this must not deadlock
        //
        System.out.println("\n****  TEST #2 ****\n");
        System.out.println("Registering Blibby #1 with name: " + on1);
        mbs.registerMBean(new Blibby(mbs, null), on1);
        System.out.println("Registering Blibby #2 with other name: " + on2);
        mbs.registerMBean(new Blibby(mbs, on1), on2);
        if (mbs.isRegistered(on1)) {
            try {
                mbs.unregisterMBean(on1);
                if (failure == null)
                    fail(on1+" should have been unregistered");
            } catch (InstanceNotFoundException x) {
                // Race condition!
                System.out.println(on1+" was unregistered by mbean thread.");
            }
        }  else {
            System.out.println(on1+" was correctly unregistered.");
        }

        System.out.println("unregistering "+on2);
        mbs.unregisterMBean(on2);
        if (failure == previous)
            System.out.println("\n****  TEST #2 PASSED ****\n");
        previous = failure;

        if (failure == null)
            System.out.println("OK: Test passed");
        else
            throw new Exception("TEST FAILED: " + failure);
    }

    private static void fail(String why) {
        System.out.println("FAILED: " + why);
        failure = (failure == null)?why:(failure+",\n"+why);
    }

    private static volatile String failure;
}
