8050115: javax/management/monitor/GaugeMonitorDeadlockTest.java fails intermittently
Reviewed-by: dfuchs, dholmes
--- a/jdk/test/ProblemList.txt Wed Sep 17 23:27:59 2014 -0400
+++ b/jdk/test/ProblemList.txt Thu Sep 18 16:16:07 2014 +0200
@@ -139,9 +139,6 @@
com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java aix-all
javax/management/MBeanServer/OldMBeanServerTest.java aix-all
-# 8050115
-javax/management/monitor/GaugeMonitorDeadlockTest.java generic-all
-
############################################################################
# jdk_math
--- a/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Wed Sep 17 23:27:59 2014 -0400
+++ b/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Thu Sep 18 16:16:07 2014 +0200
@@ -36,8 +36,9 @@
*/
import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.management.Attribute;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.Notification;
@@ -47,10 +48,16 @@
import javax.management.monitor.GaugeMonitorMBean;
public class GaugeMonitorDeadlockTest {
+ private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
+ private static long checkingTime;
public static void main(String[] args) throws Exception {
if (args.length != 1)
throw new Exception("Arg should be test number");
+ double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0"));
+ checkingTime = (long)factor*1000;
+ System.out.println("=== checkingTime = " + checkingTime + "ms");
+
int testNo = Integer.parseInt(args[0]) - 1;
TestCase test = testCases[testNo];
System.out.println("Test: " + test.getDescription());
@@ -58,8 +65,6 @@
System.out.println("Test passed");
}
- private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
-
private static abstract class TestCase {
TestCase(String description, When when) {
this.description = description;
@@ -98,16 +103,29 @@
monitorProxy.setNotifyLow(true);
monitorProxy.start();
+ System.out.println("=== Waiting observedProxy.getGetCount() to be "
+ + "changed, presumable deadlock if timeout?");
final int initGetCount = observedProxy.getGetCount();
- int getCount = initGetCount;
- for (int i = 0; i < 2000; i++) { // 2000 * 10 = 20 seconds
- getCount = observedProxy.getGetCount();
- if (getCount != initGetCount)
- break;
- Thread.sleep(10);
+ long checkedTime = System.currentTimeMillis();
+ long nowTime;
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ while (observedProxy.getGetCount() == initGetCount) {
+ Thread.sleep(100);
+
+ nowTime = System.currentTimeMillis();
+ if (nowTime - checkedTime >= checkingTime) {
+ System.out.println("=== Checking deadlocked ...");
+ if (threadMXBean.findDeadlockedThreads() != null) {
+ for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+ System.out.println(info);
+ }
+ throw new Error("Found deadlocked threads: "
+ + threadMXBean.findDeadlockedThreads().length);
+ }
+ checkedTime = System.currentTimeMillis();
+ }
}
- if (getCount <= initGetCount)
- throw new Exception("Test failed: presumable deadlock");
+
// This won't show up as a deadlock in CTRL-\ or in
// ThreadMXBean.findDeadlockedThreads(), because they don't
// see that thread A is waiting for thread B (B.join()), and
@@ -117,13 +135,13 @@
// so if we want to test notify behaviour we can trigger by
// exceeding the threshold.
if (when == When.IN_NOTIFY) {
+ final Thread testedThread = new Thread(sensitiveThing);
final AtomicInteger notifCount = new AtomicInteger();
final NotificationListener listener = new NotificationListener() {
public void handleNotification(Notification n, Object h) {
- Thread t = new Thread(sensitiveThing);
- t.start();
+ testedThread.start();
try {
- t.join();
+ testedThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -132,12 +150,36 @@
};
mbs.addNotificationListener(monitorName, listener, null, null);
observedProxy.setThing(1000);
- for (int i = 0; i < 2000 && notifCount.get() == 0; i++)
- Thread.sleep(10);
- if (notifCount.get() == 0)
- throw new Exception("Test failed: presumable deadlock");
+ System.out.println("=== Waiting notifications, presumable "
+ + "deadlock if timeout?");
+ long startTime = System.currentTimeMillis();
+ checkedTime = startTime;
+ while (notifCount.get() == 0) {
+ Thread.sleep(100);
+
+ nowTime = System.currentTimeMillis();
+ if (nowTime - checkedTime >= checkingTime) {
+ System.out.println("=== Checking the thread state ...");
+ if (testedThread.isAlive()) {
+ System.out.println("=== Waiting testedThread to die "
+ + "after " + (nowTime - startTime) + "ms");
+
+ ThreadInfo tinfo = threadMXBean.getThreadInfo(testedThread.getId());
+ if (Thread.State.BLOCKED.equals(tinfo.getThreadState())) {
+ for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+ System.out.println(info);
+ }
+ } else {
+ System.out.println(tinfo);
+ }
+ } else {
+ System.out.println("=== The testedThread is dead as wished, "
+ + "the test must be passed soon.");
+ }
+ checkedTime = System.currentTimeMillis();
+ }
+ }
}
-
}
abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy,