/*
 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 4757273
 * @summary Test deadlock in MBeanServerDelegate listeners
 * @author Eamonn McManus
 * @modules java.management
 * @run clean NotifDeadlockTest
 * @run build NotifDeadlockTest
 * @run main NotifDeadlockTest
 */

/*
 * Test deadlock when a listener for an MBeanServerDelegate does a
 * register or unregister of an MBean.  Since such a listener is
 * triggered by a register or unregister operation, deadlock scenarios
 * are possible if there are any locks held while the listener is
 * being dispatched.
 *
 * The flow of control looks rather like this:
 *
 * Thread 1:
 * - MBeanServer.createMBean(..., objectName1);
 * --- MBeanServerDelegate.sendNotification
 * ----- XListener.handleNotification
 * ------- create Thread 2
 * ------- wait for Thread 2 to complete
 *
 * Thread 2:
 * - MBeanServer.createMBean(..., objectName2);
 * - end Thread 2
 *
 * If any locks are held by Thread 1 within createMBean or
 * sendNotification, then Thread 2 can block waiting for them.
 * Since Thread 1 is itself waiting for Thread 2, this is a deadlock.
 *
 * We test all four combinations of:
 * (Thread1-create,Thread1-unregister) x (Thread2-create,Thread2-unregister)
 *
 * In the JMX 1.1 RI, all four tests fail.  In the JMX 1.2 RI, all four
 * tests should pass.
 */
import javax.management.*;

public class NotifDeadlockTest {
    static ObjectName on1, on2, delName;
    static {
        try {
            on1 = new ObjectName("thing:a=b");
            on2 = new ObjectName("thing:c=d");
            delName =
                new ObjectName("JMImplementation:type=MBeanServerDelegate");
        } catch (MalformedObjectNameException e) {
            throw new Error();
        }
    }
    static MBeanServer mbs;
    static boolean timedOut;

    /* This listener registers or unregisters the MBean called on2
       when triggered.  */
    private static class XListener implements NotificationListener {
        private boolean firstTime = true;
        private final boolean register;

        XListener(boolean register) {
            this.register = register;
        }

        public void handleNotification(Notification not, Object handback) {
            if (firstTime) {
                firstTime = false;
                Thread t = new Thread() {
                    public void run() {
                        try {
                            if (register) {
                                mbs.createMBean("javax.management.timer.Timer",
                                                on2);
                                System.out.println("Listener created " + on2);
                            } else {
                                mbs.unregisterMBean(on2);
                                System.out.println("Listener removed " + on2);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
                t.start();
                try {
                    t.join(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace(); // should not happen
                }
                if (t.isAlive()) {
                    System.out.println("FAILURE: Wait timed out: " +
                                       "probable deadlock");
                    timedOut = true;
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        boolean success = true;

        System.out.println("Test 1: in register notif, unregister an MBean");
        timedOut = false;
        mbs = MBeanServerFactory.createMBeanServer();
        mbs.createMBean("javax.management.timer.Timer", on2);
        mbs.addNotificationListener(delName, new XListener(false), null, null);
        mbs.createMBean("javax.management.timer.Timer", on1);
        MBeanServerFactory.releaseMBeanServer(mbs);
        if (timedOut) {
            success = false;
            Thread.sleep(500);
            // wait for the spawned thread to complete its work, probably
        }
        System.out.println("Test 1 completed");

        System.out.println("Test 2: in unregister notif, unregister an MBean");
        timedOut = false;
        mbs = MBeanServerFactory.createMBeanServer();
        mbs.createMBean("javax.management.timer.Timer", on1);
        mbs.createMBean("javax.management.timer.Timer", on2);
        mbs.addNotificationListener(delName, new XListener(false), null, null);
        mbs.unregisterMBean(on1);
        MBeanServerFactory.releaseMBeanServer(mbs);
        if (timedOut) {
            success = false;
            Thread.sleep(500);
            // wait for the spawned thread to complete its work, probably
        }
        System.out.println("Test 2 completed");

        System.out.println("Test 3: in register notif, register an MBean");
        timedOut = false;
        mbs = MBeanServerFactory.createMBeanServer();
        mbs.addNotificationListener(delName, new XListener(true), null, null);
        mbs.createMBean("javax.management.timer.Timer", on1);
        MBeanServerFactory.releaseMBeanServer(mbs);
        if (timedOut) {
            success = false;
            Thread.sleep(500);
            // wait for the spawned thread to complete its work, probably
        }
        System.out.println("Test 3 completed");

        System.out.println("Test 4: in unregister notif, register an MBean");
        timedOut = false;
        mbs = MBeanServerFactory.createMBeanServer();
        mbs.createMBean("javax.management.timer.Timer", on1);
        mbs.addNotificationListener(delName, new XListener(true), null, null);
        mbs.unregisterMBean(on1);
        MBeanServerFactory.releaseMBeanServer(mbs);
        if (timedOut) {
            success = false;
            Thread.sleep(500);
            // wait for the spawned thread to complete its work, probably
        }
        System.out.println("Test 4 completed");

        if (success)
            System.out.println("Test passed");
        else {
            System.out.println("TEST FAILED: at least one subcase failed");
            System.exit(1);
        }
    }
}
