--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/standardmbean/DeadlockTest.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,172 @@
+/*
+ * 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 6331746
+ * @summary Deadlock on synchronization problem
+ * @author Shanliang JIANG
+ * @run main DeadlockTest
+ */
+
+import javax.management.*;
+import javax.management.timer.*;
+
+public class DeadlockTest extends StandardMBean {
+ public <T> DeadlockTest(T implementation, Class<T> mbeanInterface)
+ throws NotCompliantMBeanException {
+ super(implementation, mbeanInterface);
+ }
+
+ public MBeanInfo getCachedMBeanInfo() {
+ return super.getCachedMBeanInfo();
+ }
+
+ public void cacheMBeanInfo(MBeanInfo mi) {
+ super.cacheMBeanInfo(mi);
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("main: No deadlock please.");
+
+ System.out.println("main: Create a BadBay to hold the lock forever.");
+ DeadlockTest dt = new DeadlockTest(new Timer(), TimerMBean.class);
+
+ BadBoy bb = new BadBoy(dt);
+ bb.start();
+
+ final long timeout = 2000;
+ long stopTime = System.currentTimeMillis() + timeout;
+ long timeToWait = timeout;
+ synchronized(bb) {
+ while(!bb.gotLock || timeToWait > 0) {
+ bb.wait(timeToWait);
+
+ timeToWait = stopTime - System.currentTimeMillis();
+ }
+ }
+
+ if (!bb.gotLock) {
+ throw new RuntimeException("Failed to get lock, impossible!");
+ }
+
+ System.out.println("main: The BadBay is holding the lock forever.");
+
+ System.out.println("main: Create a WorkingBoy to see blocking ...");
+ WorkingBoy wb = new WorkingBoy(dt);
+
+ stopTime = System.currentTimeMillis() + timeout;
+ timeToWait = timeout;
+
+ synchronized(wb) {
+ wb.start();
+
+ while(!wb.done || timeToWait > 0) {
+ wb.wait(timeToWait);
+
+ timeToWait = stopTime - System.currentTimeMillis();
+ }
+ }
+
+ if (!wb.done) {
+ throw new RuntimeException("It is blocked!");
+ }
+
+ System.out.println("main: OK, bye bye.");
+ }
+
+ private static class BadBoy extends Thread {
+ public BadBoy(Object o) {
+ setDaemon(true);
+
+ this.o = o;
+ }
+
+ public void run() {
+ System.out.println("BadBoy-run: keep synchronization lock forever!");
+
+ synchronized(o) {
+ synchronized(this) {
+ gotLock = true;
+
+ this.notify();
+ }
+
+ try {
+ Thread.sleep(10000000);
+ } catch (Exception e) {
+ // OK
+ }
+ }
+ }
+
+ final Object o;
+ public boolean gotLock;
+ }
+
+ private static class WorkingBoy extends Thread {
+ public WorkingBoy(DeadlockTest sm) {
+ setDaemon(true);
+
+ this.sm = sm;
+ }
+
+ public void run() {
+ try {
+ System.out.println("WorkingBoy-run: calling StandardMBean methods ...");
+
+ System.out.println("WorkingBoy-run: calling setImplementation ...");
+ sm.setImplementation(new Timer());
+
+ System.out.println("WorkingBoy-run: calling getImplementation ...");
+ sm.getImplementation();
+
+ System.out.println("WorkingBoy-run: calling getMBeanInterface ...");
+ sm.getMBeanInterface();
+
+ System.out.println("WorkingBoy-run: calling getImplementationClass ...");
+ sm.getImplementationClass();
+
+ System.out.println("WorkingBoy-run: calling cacheMBeanInfo ...");
+ sm.cacheMBeanInfo(null);
+
+ System.out.println("WorkingBoy-run: calling getCachedMBeanInfo ...");
+ sm.getCachedMBeanInfo();
+
+ System.out.println("WorkingBoy-run: All done!");
+
+ synchronized(this) {
+ done = true;
+
+ this.notifyAll();
+ }
+ } catch (NotCompliantMBeanException ne) {
+ // Impossible?
+ throw new RuntimeException(ne);
+ }
+ }
+
+ final DeadlockTest sm;
+ public boolean done;
+ }
+}