Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java
38838 views
1
/*
2
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @bug 6303187
27
* @summary Test that no locks are held when a monitor attribute is sampled
28
* or notif delivered.
29
* @author Eamonn McManus
30
* @library /lib/testlibrary
31
* @run clean GaugeMonitorDeadlockTest
32
* @run build GaugeMonitorDeadlockTest
33
* @run main GaugeMonitorDeadlockTest 1
34
* @run main GaugeMonitorDeadlockTest 2
35
* @run main GaugeMonitorDeadlockTest 3
36
* @run main GaugeMonitorDeadlockTest 4
37
*/
38
39
import java.lang.management.ManagementFactory;
40
import java.lang.management.ThreadInfo;
41
import java.lang.management.ThreadMXBean;
42
import java.util.concurrent.atomic.AtomicInteger;
43
import javax.management.JMX;
44
import javax.management.MBeanServer;
45
import javax.management.Notification;
46
import javax.management.NotificationListener;
47
import javax.management.ObjectName;
48
import javax.management.monitor.GaugeMonitor;
49
import javax.management.monitor.GaugeMonitorMBean;
50
51
import jdk.testlibrary.Utils;
52
53
public class GaugeMonitorDeadlockTest {
54
private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
55
private static long checkingTime;
56
57
public static void main(String[] args) throws Exception {
58
if (args.length != 1)
59
throw new Exception("Arg should be test number");
60
checkingTime = Utils.adjustTimeout(1000); // default 1s timeout
61
System.out.println("=== checkingTime = " + checkingTime + "ms");
62
63
int testNo = Integer.parseInt(args[0]) - 1;
64
TestCase test = testCases[testNo];
65
System.out.println("Test: " + test.getDescription());
66
test.run();
67
System.out.println("Test passed");
68
}
69
70
private static abstract class TestCase {
71
TestCase(String description, When when) {
72
this.description = description;
73
this.when = when;
74
}
75
76
void run() throws Exception {
77
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
78
final ObjectName observedName = new ObjectName("a:b=c");
79
final ObjectName monitorName = new ObjectName("a:type=Monitor");
80
mbs.registerMBean(new GaugeMonitor(), monitorName);
81
final GaugeMonitorMBean monitorProxy =
82
JMX.newMBeanProxy(mbs, monitorName, GaugeMonitorMBean.class);
83
final TestMBean observedProxy =
84
JMX.newMBeanProxy(mbs, observedName, TestMBean.class);
85
86
final Runnable sensitiveThing = new Runnable() {
87
public void run() {
88
doSensitiveThing(monitorProxy, observedName);
89
}
90
};
91
92
final Runnable nothing = new Runnable() {
93
public void run() {}
94
};
95
96
final Runnable withinGetAttribute =
97
(when == When.IN_GET_ATTRIBUTE) ? sensitiveThing : nothing;
98
99
mbs.registerMBean(new Test(withinGetAttribute), observedName);
100
monitorProxy.addObservedObject(observedName);
101
monitorProxy.setObservedAttribute("Thing");
102
monitorProxy.setThresholds(105, 100);
103
monitorProxy.setGranularityPeriod(10L); // 10 ms
104
monitorProxy.setNotifyHigh(true);
105
monitorProxy.setNotifyLow(true);
106
107
System.out.println("=== Waiting observedProxy.getGetCount() to be "
108
+ "changed, presumable deadlock if timeout?");
109
final int initGetCount = observedProxy.getGetCount();
110
monitorProxy.start();
111
112
long checkedTime = System.currentTimeMillis();
113
long nowTime;
114
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
115
while (observedProxy.getGetCount() == initGetCount) {
116
Thread.sleep(100);
117
118
nowTime = System.currentTimeMillis();
119
if (nowTime - checkedTime >= checkingTime) {
120
System.out.println("=== Checking deadlocked ...");
121
if (threadMXBean.findDeadlockedThreads() != null) {
122
for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
123
System.out.println(info);
124
}
125
throw new Error("Found deadlocked threads: "
126
+ threadMXBean.findDeadlockedThreads().length);
127
}
128
checkedTime = System.currentTimeMillis();
129
}
130
}
131
132
// This won't show up as a deadlock in CTRL-\ or in
133
// ThreadMXBean.findDeadlockedThreads(), because they don't
134
// see that thread A is waiting for thread B (B.join()), and
135
// thread B is waiting for a lock held by thread A
136
137
// Now we know the monitor has observed the initial value,
138
// so if we want to test notify behaviour we can trigger by
139
// exceeding the threshold.
140
if (when == When.IN_NOTIFY) {
141
final Thread testedThread = new Thread(sensitiveThing);
142
final AtomicInteger notifCount = new AtomicInteger();
143
final NotificationListener listener = new NotificationListener() {
144
public void handleNotification(Notification n, Object h) {
145
testedThread.start();
146
try {
147
testedThread.join();
148
} catch (InterruptedException e) {
149
throw new RuntimeException(e);
150
}
151
notifCount.incrementAndGet();
152
}
153
};
154
mbs.addNotificationListener(monitorName, listener, null, null);
155
observedProxy.setThing(1000);
156
System.out.println("=== Waiting notifications, presumable "
157
+ "deadlock if timeout?");
158
long startTime = System.currentTimeMillis();
159
checkedTime = startTime;
160
while (notifCount.get() == 0) {
161
Thread.sleep(100);
162
163
nowTime = System.currentTimeMillis();
164
if (nowTime - checkedTime >= checkingTime) {
165
System.out.println("=== Checking the thread state ...");
166
if (testedThread.isAlive()) {
167
System.out.println("=== Waiting testedThread to die "
168
+ "after " + (nowTime - startTime) + "ms");
169
170
ThreadInfo tinfo = threadMXBean.getThreadInfo(testedThread.getId());
171
if (Thread.State.BLOCKED.equals(tinfo.getThreadState())) {
172
for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
173
System.out.println(info);
174
}
175
} else {
176
System.out.println(tinfo);
177
}
178
} else {
179
System.out.println("=== The testedThread is dead as wished, "
180
+ "the test must be passed soon.");
181
}
182
checkedTime = System.currentTimeMillis();
183
}
184
}
185
}
186
}
187
188
abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy,
189
ObjectName observedName);
190
191
String getDescription() {
192
return description;
193
}
194
195
private final String description;
196
private final When when;
197
}
198
199
private static final TestCase[] testCases = {
200
new TestCase("Remove monitored MBean within monitored getAttribute",
201
When.IN_GET_ATTRIBUTE) {
202
@Override
203
void doSensitiveThing(GaugeMonitorMBean monitorProxy,
204
ObjectName observedName) {
205
monitorProxy.removeObservedObject(observedName);
206
}
207
},
208
new TestCase("Stop monitor within monitored getAttribute",
209
When.IN_GET_ATTRIBUTE) {
210
@Override
211
void doSensitiveThing(GaugeMonitorMBean monitorProxy,
212
ObjectName observedName) {
213
monitorProxy.stop();
214
}
215
},
216
new TestCase("Remove monitored MBean within threshold listener",
217
When.IN_NOTIFY) {
218
@Override
219
void doSensitiveThing(GaugeMonitorMBean monitorProxy,
220
ObjectName observedName) {
221
monitorProxy.removeObservedObject(observedName);
222
}
223
},
224
new TestCase("Stop monitor within threshold listener",
225
When.IN_NOTIFY) {
226
@Override
227
void doSensitiveThing(GaugeMonitorMBean monitorProxy,
228
ObjectName observedName) {
229
monitorProxy.stop();
230
}
231
},
232
};
233
234
public static interface TestMBean {
235
public int getThing();
236
public void setThing(int thing);
237
public int getGetCount();
238
}
239
240
public static class Test implements TestMBean {
241
public Test(Runnable runWithinGetAttribute) {
242
this.runWithinGetAttribute = runWithinGetAttribute;
243
}
244
245
public int getThing() {
246
Thread t = new Thread(runWithinGetAttribute);
247
t.start();
248
try {
249
t.join();
250
} catch (InterruptedException e) {
251
throw new RuntimeException(e);
252
}
253
getCount++;
254
return thing;
255
}
256
257
public void setThing(int thing) {
258
this.thing = thing;
259
}
260
261
public int getGetCount() {
262
return getCount;
263
}
264
265
private final Runnable runWithinGetAttribute;
266
private volatile int getCount;
267
private volatile int thing;
268
}
269
}
270
271