Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java
38839 views
/*1* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 630318726* @summary Test that no locks are held when a monitor attribute is sampled27* or notif delivered.28* @author Eamonn McManus29* @run clean CounterMonitorDeadlockTest30* @run build CounterMonitorDeadlockTest31* @run main CounterMonitorDeadlockTest 132* @run main CounterMonitorDeadlockTest 233* @run main CounterMonitorDeadlockTest 334* @run main CounterMonitorDeadlockTest 435*/3637import java.lang.management.ManagementFactory;38import java.util.concurrent.atomic.AtomicInteger;39import javax.management.JMX;40import javax.management.MBeanServer;41import javax.management.Notification;42import javax.management.NotificationListener;43import javax.management.ObjectName;44import javax.management.monitor.CounterMonitor;45import javax.management.monitor.CounterMonitorMBean;4647public class CounterMonitorDeadlockTest {4849public static void main(String[] args) throws Exception {50if (args.length != 1)51throw new Exception("Arg should be test number");52int testNo = Integer.parseInt(args[0]) - 1;53TestCase test = testCases[testNo];54System.out.println("Test: " + test.getDescription());55test.run();56System.out.println("Test passed");57}5859private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};6061private static abstract class TestCase {62TestCase(String description, When when) {63this.description = description;64this.when = when;65}6667void run() throws Exception {68final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();69final ObjectName observedName = new ObjectName("a:b=c");70final ObjectName monitorName = new ObjectName("a:type=Monitor");71mbs.registerMBean(new CounterMonitor(), monitorName);72final CounterMonitorMBean monitorProxy =73JMX.newMBeanProxy(mbs, monitorName, CounterMonitorMBean.class);74final TestMBean observedProxy =75JMX.newMBeanProxy(mbs, observedName, TestMBean.class);7677final Runnable sensitiveThing = new Runnable() {78public void run() {79doSensitiveThing(monitorProxy, observedName);80}81};8283final Runnable nothing = new Runnable() {84public void run() {}85};8687final Runnable withinGetAttribute =88(when == When.IN_GET_ATTRIBUTE) ? sensitiveThing : nothing;8990mbs.registerMBean(new Test(withinGetAttribute), observedName);91monitorProxy.addObservedObject(observedName);92monitorProxy.setObservedAttribute("Thing");93monitorProxy.setInitThreshold(100);94monitorProxy.setGranularityPeriod(10L); // 10 ms95monitorProxy.setNotify(true);9697final int initGetCount = observedProxy.getGetCount();98monitorProxy.start();99100System.out.println("Checking GetCount, possible deadlock if timeout.");101do { // 8038322. Until timeout of testing harness102Thread.sleep(200);103} while ((observedProxy.getGetCount()) == initGetCount);104System.out.println("Done!");105106// This won't show up as a deadlock in CTRL-\ or in107// ThreadMXBean.findDeadlockedThreads(), because they don't108// see that thread A is waiting for thread B (B.join()), and109// thread B is waiting for a lock held by thread A110111// Now we know the monitor has observed the initial value,112// so if we want to test notify behaviour we can trigger by113// exceeding the threshold.114if (when == When.IN_NOTIFY) {115final AtomicInteger notifCount = new AtomicInteger();116final NotificationListener listener = new NotificationListener() {117public void handleNotification(Notification n, Object h) {118Thread t = new Thread(sensitiveThing);119t.start();120try {121t.join();122} catch (InterruptedException e) {123throw new RuntimeException(e);124}125notifCount.incrementAndGet();126}127};128mbs.addNotificationListener(monitorName, listener, null, null);129observedProxy.setThing(1000);130System.out.println("Waiting notifCount.get() != 0, possible deadlock if timeout.");131do {132Thread.sleep(200);133} while(notifCount.get() == 0); // 8038322. Until timeout of testing harness134System.out.println("Done");135}136137}138139abstract void doSensitiveThing(CounterMonitorMBean monitorProxy,140ObjectName observedName);141142String getDescription() {143return description;144}145146private final String description;147private final When when;148}149150private static final TestCase[] testCases = {151new TestCase("Remove monitored MBean within monitored getAttribute",152When.IN_GET_ATTRIBUTE) {153@Override154void doSensitiveThing(CounterMonitorMBean monitorProxy,155ObjectName observedName) {156monitorProxy.removeObservedObject(observedName);157}158},159new TestCase("Stop monitor within monitored getAttribute",160When.IN_GET_ATTRIBUTE) {161@Override162void doSensitiveThing(CounterMonitorMBean monitorProxy,163ObjectName observedName) {164monitorProxy.stop();165}166},167new TestCase("Remove monitored MBean within threshold listener",168When.IN_NOTIFY) {169@Override170void doSensitiveThing(CounterMonitorMBean monitorProxy,171ObjectName observedName) {172monitorProxy.removeObservedObject(observedName);173}174},175new TestCase("Stop monitor within threshold listener",176When.IN_NOTIFY) {177@Override178void doSensitiveThing(CounterMonitorMBean monitorProxy,179ObjectName observedName) {180monitorProxy.stop();181}182},183};184185public static interface TestMBean {186public int getThing();187public void setThing(int thing);188public int getGetCount();189}190191public static class Test implements TestMBean {192public Test(Runnable runWithinGetAttribute) {193this.runWithinGetAttribute = runWithinGetAttribute;194}195196public int getThing() {197Thread t = new Thread(runWithinGetAttribute);198t.start();199try {200t.join();201} catch (InterruptedException e) {202throw new RuntimeException(e);203}204getCount++;205return thing;206}207208public void setThing(int thing) {209this.thing = thing;210}211212public int getGetCount() {213return getCount;214}215216private final Runnable runWithinGetAttribute;217private volatile int getCount;218private volatile int thing;219}220}221222223