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/notification/BroadcasterSupportDeadlockTest.java
38840 views
1
/*
2
* Copyright (c) 2004, 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 5093922 2120055
27
* @summary Test that NotificationBroadcasterSupport can be subclassed
28
* and used with synchronized(this) without causing deadlock
29
* @author Eamonn McManus
30
* @run clean BroadcasterSupportDeadlockTest
31
* @run build BroadcasterSupportDeadlockTest
32
* @run main BroadcasterSupportDeadlockTest
33
*/
34
35
import java.lang.management.*;
36
import java.util.concurrent.*;
37
import javax.management.*;
38
39
public class BroadcasterSupportDeadlockTest {
40
public static void main(String[] args) throws Exception {
41
try {
42
Class.forName(ManagementFactory.class.getName());
43
} catch (Throwable t) {
44
System.out.println("TEST CANNOT RUN: needs JDK 5 at least");
45
return;
46
}
47
48
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
49
final BroadcasterMBean mbean = new Broadcaster();
50
final ObjectName name = new ObjectName("test:type=Broadcaster");
51
mbs.registerMBean(mbean, name);
52
53
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
54
threads.setThreadContentionMonitoringEnabled(true);
55
56
final Semaphore semaphore = new Semaphore(0);
57
58
// Thread 1 - block the Broadcaster
59
Thread t1 = new Thread() {
60
public void run() {
61
try {
62
mbs.invoke(name, "block",
63
new Object[] {semaphore},
64
new String[] {Semaphore.class.getName()});
65
} catch (Exception e) {
66
e.printStackTrace(System.out);
67
} finally {
68
System.out.println("TEST INCORRECT: block returned");
69
System.exit(1);
70
}
71
}
72
};
73
t1.setDaemon(true);
74
t1.start();
75
76
/* Wait for Thread 1 to be doing Object.wait(). It's very
77
difficult to synchronize properly here so we wait for the
78
semaphore, then wait a little longer for the mbs.invoke to
79
run, then just in case that isn't enough, we wait for the
80
thread to be in WAITING state. This isn't foolproof,
81
because the machine could be very slow and the
82
Thread.getState() could find the thread in WAITING state
83
due to some operation it does on its way to the one we're
84
interested in. */
85
semaphore.acquire();
86
Thread.sleep(100);
87
while (t1.getState() != Thread.State.WAITING)
88
Thread.sleep(1);
89
90
// Thread 2 - try to add a listener
91
final NotificationListener listener = new NotificationListener() {
92
public void handleNotification(Notification n, Object h) {}
93
};
94
Thread t2 = new Thread() {
95
public void run() {
96
try {
97
mbs.addNotificationListener(name, listener, null, null);
98
} catch (Exception e) {
99
System.out.println("TEST INCORRECT: addNL failed:");
100
e.printStackTrace(System.out);
101
}
102
}
103
};
104
t2.setDaemon(true);
105
t2.start();
106
107
/* Wait for Thread 2 to be blocked on the monitor or to
108
succeed. */
109
Thread.sleep(100);
110
111
for (int i = 0; i < 1000/*ms*/; i++) {
112
t2.join(1/*ms*/);
113
switch (t2.getState()) {
114
case TERMINATED:
115
System.out.println("TEST PASSED");
116
return;
117
case BLOCKED:
118
java.util.Map<Thread,StackTraceElement[]> traces =
119
Thread.getAllStackTraces();
120
showStackTrace("Thread 1", traces.get(t1));
121
showStackTrace("Thread 2", traces.get(t2));
122
System.out.println("TEST FAILED: deadlock");
123
System.exit(1);
124
break;
125
default:
126
break;
127
}
128
}
129
130
System.out.println("TEST FAILED BUT DID NOT NOTICE DEADLOCK");
131
Thread.sleep(10000);
132
System.exit(1);
133
}
134
135
private static void showStackTrace(String title,
136
StackTraceElement[] stack) {
137
System.out.println("---" + title + "---");
138
if (stack == null)
139
System.out.println("<no stack trace???>");
140
else {
141
for (StackTraceElement elmt : stack)
142
System.out.println(" " + elmt);
143
}
144
System.out.println();
145
}
146
147
public static interface BroadcasterMBean {
148
public void block(Semaphore semaphore);
149
}
150
151
public static class Broadcaster
152
extends NotificationBroadcasterSupport
153
implements BroadcasterMBean {
154
public synchronized void block(Semaphore semaphore) {
155
Object lock = new Object();
156
synchronized (lock) {
157
try {
158
// Let the caller know that it can now wait for us to
159
// hit the WAITING state
160
semaphore.release();
161
lock.wait(); // block forever
162
} catch (InterruptedException e) {
163
System.out.println("TEST INCORRECT: lock interrupted:");
164
e.printStackTrace(System.out);
165
System.exit(1);
166
}
167
}
168
}
169
}
170
}
171
172