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/remote/mandatory/connection/MultiThreadDeadLockTest.java
38867 views
1
/*
2
* Copyright (c) 2008, 2013, 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
import java.io.IOException;
26
import java.io.Serializable;
27
import java.net.Socket;
28
import java.rmi.server.RMIClientSocketFactory;
29
import java.util.HashMap;
30
import javax.management.MBeanServer;
31
import javax.management.MBeanServerFactory;
32
import javax.management.Notification;
33
import javax.management.NotificationBroadcasterSupport;
34
import javax.management.NotificationListener;
35
import javax.management.ObjectName;
36
import javax.management.remote.JMXConnector;
37
import javax.management.remote.JMXConnectorFactory;
38
import javax.management.remote.JMXConnectorServer;
39
import javax.management.remote.JMXConnectorServerFactory;
40
import javax.management.remote.JMXServiceURL;
41
import javax.management.remote.rmi.RMIConnectorServer;
42
43
/*
44
* @test
45
* @bug 6697180
46
* @summary test on a client notification deadlock.
47
* @author Shanliang JIANG
48
* @run clean MultiThreadDeadLockTest
49
* @run build MultiThreadDeadLockTest
50
* @run main MultiThreadDeadLockTest
51
*/
52
53
public class MultiThreadDeadLockTest {
54
55
private static long serverTimeout = 500L;
56
57
public static void main(String[] args) throws Exception {
58
print("Create the MBean server");
59
MBeanServer mbs = MBeanServerFactory.createMBeanServer();
60
61
print("Initialize environment map");
62
HashMap env = new HashMap();
63
64
print("Specify a client socket factory to control socket creation.");
65
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
66
clientFactory);
67
68
print("Specify a server idle timeout to make a server close an idle connection.");
69
env.put("jmx.remote.x.server.connection.timeout", serverTimeout);
70
71
print("Disable client heartbeat.");
72
env.put("jmx.remote.x.client.connection.check.period", 0);
73
74
env.put("jmx.remote.x.notification.fetch.timeout", serverTimeout);
75
76
print("Create an RMI server");
77
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
78
JMXConnectorServer server =
79
JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
80
server.start();
81
82
url = server.getAddress();
83
84
print("Create jmx client on "+url);
85
StateMachine.setState(CREATE_SOCKET); // allow to create client socket
86
client = JMXConnectorFactory.connect(url, env);
87
Thread.sleep(100);
88
89
totoName = new ObjectName("default:name=toto");
90
mbs.registerMBean(toto, totoName);
91
print("Register the mbean: " + totoName);
92
93
print("Add listener to toto MBean");
94
client.getMBeanServerConnection().addNotificationListener(
95
totoName, myListener, null, null);
96
Thread.sleep(10);
97
98
print("send notif, listener will block the fetcher");
99
toto.sendNotif();
100
Thread.sleep(100);
101
102
StateMachine.setState(NO_OP);
103
104
print("Sleep 3 times of server idle timeout: "+serverTimeout+
105
", the sever should close the idle connection.");
106
Thread.sleep(serverTimeout*3);
107
108
print("start the user thread to call mbean method, it will get IOexception" +
109
" and start the reconnection, the socket factory will block the" +
110
" socket creation.");
111
UserThread ut = new UserThread();
112
ut.start();
113
Thread.sleep(10);
114
115
print("Free the listener, the fetcher will get IO and makes " +
116
"a deadlock if the bug is not fixed.");
117
StateMachine.setState(FREE_LISTENER);
118
Thread.sleep(100);
119
120
print("Allow to create new socket for the reconnection");
121
StateMachine.setState(CREATE_SOCKET);
122
123
print("Check whether the user thread gets free to call the mbean.");
124
if (!ut.waitDone(5000)) {
125
throw new RuntimeException("Possible deadlock!");
126
}
127
128
print("Remove the listener.");
129
client.getMBeanServerConnection().removeNotificationListener(
130
totoName, myListener, null, null);
131
Thread.sleep(serverTimeout*3);
132
133
print("\nWell passed, bye!");
134
135
client.close();
136
Thread.sleep(10);
137
server.stop();
138
}
139
140
private static ObjectName totoName = null;
141
private static JMXConnector client;
142
143
public static class UserThread extends Thread {
144
public UserThread() {
145
setDaemon(true);
146
}
147
148
public void run() {
149
try {
150
client.getMBeanServerConnection().invoke(
151
totoName, "allowReturn", null, null);
152
} catch (Exception e) {
153
throw new Error(e);
154
}
155
156
synchronized(UserThread.class) {
157
done = true;
158
UserThread.class.notify();
159
}
160
}
161
162
public boolean waitDone(long timeout) {
163
synchronized(UserThread.class) {
164
if(!done) {
165
try {
166
UserThread.class.wait(timeout);
167
} catch (Exception e) {
168
throw new Error(e);
169
}
170
}
171
}
172
return done;
173
}
174
175
private boolean done = false;
176
}
177
178
public static interface TotoMBean {
179
public void allowReturn();
180
}
181
182
public static class Toto extends NotificationBroadcasterSupport
183
implements TotoMBean {
184
185
public void allowReturn() {
186
enter("allowReturn");
187
188
leave("allowReturn");
189
}
190
191
public void sendNotif() {
192
enter("sendNotif");
193
194
sendNotification(new Notification("Toto", totoName, 0));
195
196
leave("sendNotif");
197
}
198
}
199
private static Toto toto = new Toto();
200
201
public static NotificationListener myListener = new NotificationListener() {
202
public void handleNotification(Notification notification, Object handback) {
203
enter("handleNotification");
204
205
StateMachine.waitState(FREE_LISTENER);
206
207
leave("handleNotification");
208
}
209
};
210
211
public static class RMIClientFactory
212
implements RMIClientSocketFactory, Serializable {
213
214
public Socket createSocket(String host, int port) throws IOException {
215
enter("createSocket");
216
//print("Calling createSocket(" + host + " " + port + ")");
217
218
StateMachine.waitState(CREATE_SOCKET);
219
Socket s = new Socket(host, port);
220
leave("createSocket");
221
222
return s;
223
}
224
}
225
private static RMIClientFactory clientFactory = new RMIClientFactory();
226
227
private static int CREATE_SOCKET = 1;
228
private static int FREE_LISTENER = 3;
229
private static int NO_OP = 0;
230
231
public static class StateMachine {
232
233
private static int state = NO_OP;
234
private static int[] lock = new int[0];
235
236
public static void waitState(int s) {
237
synchronized (lock) {
238
while (state != s) {
239
try {
240
lock.wait();
241
} catch (InterruptedException ire) {
242
// should not
243
throw new Error(ire);
244
}
245
}
246
}
247
}
248
249
public static int getState() {
250
synchronized (lock) {
251
return state;
252
}
253
}
254
255
public static void setState(int s) {
256
synchronized (lock) {
257
state = s;
258
lock.notifyAll();
259
}
260
}
261
}
262
263
private static void print(String m) {
264
System.out.println(m);
265
}
266
267
private static void enter(String m) {
268
System.out.println("\n---Enter the method " + m);
269
}
270
271
private static void leave(String m) {
272
System.out.println("===Leave the method: " + m);
273
}
274
}
275
276