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