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/StringMonitorDeadlockTest.java
38838 views
1
/*
2
* Copyright (c) 2005, 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
* @run clean StringMonitorDeadlockTest
31
* @run build StringMonitorDeadlockTest
32
* @run main StringMonitorDeadlockTest 1
33
* @run main StringMonitorDeadlockTest 2
34
* @run main StringMonitorDeadlockTest 3
35
* @run main StringMonitorDeadlockTest 4
36
*/
37
38
import java.lang.management.ManagementFactory;
39
import java.util.concurrent.atomic.AtomicInteger;
40
import javax.management.JMX;
41
import javax.management.MBeanServer;
42
import javax.management.Notification;
43
import javax.management.NotificationListener;
44
import javax.management.ObjectName;
45
import javax.management.monitor.StringMonitor;
46
import javax.management.monitor.StringMonitorMBean;
47
48
public class StringMonitorDeadlockTest {
49
50
public static void main(String[] args) throws Exception {
51
if (args.length != 1)
52
throw new Exception("Arg should be test number");
53
int testNo = Integer.parseInt(args[0]) - 1;
54
TestCase test = testCases[testNo];
55
System.out.println("Test: " + test.getDescription());
56
test.run();
57
System.out.println("Test passed");
58
}
59
60
private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
61
62
private static abstract class TestCase {
63
TestCase(String description, When when) {
64
this.description = description;
65
this.when = when;
66
}
67
68
void run() throws Exception {
69
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
70
final ObjectName observedName = new ObjectName("a:b=c");
71
final ObjectName monitorName = new ObjectName("a:type=Monitor");
72
mbs.registerMBean(new StringMonitor(), monitorName);
73
final StringMonitorMBean monitorProxy =
74
JMX.newMBeanProxy(mbs, monitorName, StringMonitorMBean.class);
75
final TestMBean observedProxy =
76
JMX.newMBeanProxy(mbs, observedName, TestMBean.class);
77
78
final Runnable sensitiveThing = new Runnable() {
79
public void run() {
80
doSensitiveThing(monitorProxy, observedName);
81
}
82
};
83
84
final Runnable nothing = new Runnable() {
85
public void run() {}
86
};
87
88
final Runnable withinGetAttribute =
89
(when == When.IN_GET_ATTRIBUTE) ? sensitiveThing : nothing;
90
91
mbs.registerMBean(new Test(withinGetAttribute), observedName);
92
monitorProxy.addObservedObject(observedName);
93
monitorProxy.setObservedAttribute("Thing");
94
monitorProxy.setStringToCompare("old");
95
monitorProxy.setGranularityPeriod(10L); // 10 ms
96
monitorProxy.setNotifyDiffer(true);
97
98
final int initGetCount = observedProxy.getGetCount();
99
monitorProxy.start();
100
101
int getCount = initGetCount;
102
for (int i = 0; i < 500; i++) { // 500 * 10 = 5 seconds
103
getCount = observedProxy.getGetCount();
104
if (getCount != initGetCount)
105
break;
106
Thread.sleep(10);
107
}
108
if (getCount <= initGetCount)
109
throw new Exception("Test failed: presumable deadlock");
110
// This won't show up as a deadlock in CTRL-\ or in
111
// ThreadMXBean.findDeadlockedThreads(), because they don't
112
// see that thread A is waiting for thread B (B.join()), and
113
// thread B is waiting for a lock held by thread A
114
115
// Now we know the monitor has observed the initial value,
116
// so if we want to test notify behaviour we can trigger by
117
// exceeding the threshold.
118
if (when == When.IN_NOTIFY) {
119
final AtomicInteger notifCount = new AtomicInteger();
120
final NotificationListener listener = new NotificationListener() {
121
public void handleNotification(Notification n, Object h) {
122
Thread t = new Thread(sensitiveThing);
123
t.start();
124
try {
125
t.join();
126
} catch (InterruptedException e) {
127
throw new RuntimeException(e);
128
}
129
notifCount.incrementAndGet();
130
}
131
};
132
mbs.addNotificationListener(monitorName, listener, null, null);
133
observedProxy.setThing("new");
134
for (int i = 0; i < 500 && notifCount.get() == 0; i++)
135
Thread.sleep(10);
136
if (notifCount.get() == 0)
137
throw new Exception("Test failed: presumable deadlock");
138
}
139
140
}
141
142
abstract void doSensitiveThing(StringMonitorMBean monitorProxy,
143
ObjectName observedName);
144
145
String getDescription() {
146
return description;
147
}
148
149
private final String description;
150
private final When when;
151
}
152
153
private static final TestCase[] testCases = {
154
new TestCase("Remove monitored MBean within monitored getAttribute",
155
When.IN_GET_ATTRIBUTE) {
156
@Override
157
void doSensitiveThing(StringMonitorMBean monitorProxy,
158
ObjectName observedName) {
159
monitorProxy.removeObservedObject(observedName);
160
}
161
},
162
new TestCase("Stop monitor within monitored getAttribute",
163
When.IN_GET_ATTRIBUTE) {
164
@Override
165
void doSensitiveThing(StringMonitorMBean monitorProxy,
166
ObjectName observedName) {
167
monitorProxy.stop();
168
}
169
},
170
new TestCase("Remove monitored MBean within threshold listener",
171
When.IN_NOTIFY) {
172
@Override
173
void doSensitiveThing(StringMonitorMBean monitorProxy,
174
ObjectName observedName) {
175
monitorProxy.removeObservedObject(observedName);
176
}
177
},
178
new TestCase("Stop monitor within threshold listener",
179
When.IN_NOTIFY) {
180
@Override
181
void doSensitiveThing(StringMonitorMBean monitorProxy,
182
ObjectName observedName) {
183
monitorProxy.stop();
184
}
185
},
186
};
187
188
public static interface TestMBean {
189
public String getThing();
190
public void setThing(String thing);
191
public int getGetCount();
192
}
193
194
public static class Test implements TestMBean {
195
public Test(Runnable runWithinGetAttribute) {
196
this.runWithinGetAttribute = runWithinGetAttribute;
197
}
198
199
public String getThing() {
200
Thread t = new Thread(runWithinGetAttribute);
201
t.start();
202
try {
203
t.join();
204
} catch (InterruptedException e) {
205
throw new RuntimeException(e);
206
}
207
getCount++;
208
return thing;
209
}
210
211
public void setThing(String thing) {
212
this.thing = thing;
213
}
214
215
public int getGetCount() {
216
return getCount;
217
}
218
219
private final Runnable runWithinGetAttribute;
220
private volatile int getCount;
221
private volatile String thing;
222
}
223
}
224
225