Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/tools/jdi/EventQueueImpl.java
38920 views
1
/*
2
* Copyright (c) 1998, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.tools.jdi;
27
28
import com.sun.jdi.*;
29
import com.sun.jdi.event.EventQueue;
30
import com.sun.jdi.event.EventSet;
31
32
import java.util.*;
33
34
public class EventQueueImpl extends MirrorImpl implements EventQueue {
35
36
/*
37
* Note this is not a synchronized list. Iteration/update should be
38
* protected through the 'this' monitor.
39
*/
40
LinkedList<EventSet> eventSets = new LinkedList<EventSet>();
41
42
TargetVM target;
43
boolean closed = false;
44
45
EventQueueImpl(VirtualMachine vm, TargetVM target) {
46
super(vm);
47
this.target = target;
48
target.addEventQueue(this);
49
}
50
51
/*
52
* Override superclass back to default equality
53
*/
54
public boolean equals(Object obj) {
55
return this == obj;
56
}
57
58
public int hashCode() {
59
return System.identityHashCode(this);
60
}
61
62
synchronized void enqueue(EventSet eventSet) {
63
eventSets.add(eventSet);
64
notifyAll();
65
}
66
67
synchronized int size() {
68
return eventSets.size();
69
}
70
71
synchronized void close() {
72
if (!closed) {
73
closed = true; // OK for this the be first since synchronized
74
75
// place VMDisconnectEvent into queue
76
enqueue(new EventSetImpl(vm,
77
(byte)JDWP.EventKind.VM_DISCONNECTED));
78
}
79
}
80
81
public EventSet remove() throws InterruptedException {
82
return remove(0);
83
}
84
85
/**
86
* Filter out events not for user's eyes.
87
* Then filter out empty sets.
88
*/
89
public EventSet remove(long timeout) throws InterruptedException {
90
if (timeout < 0) {
91
throw new IllegalArgumentException("Timeout cannot be negative");
92
}
93
94
EventSet eventSet;
95
while (true) {
96
EventSetImpl fullEventSet = removeUnfiltered(timeout);
97
if (fullEventSet == null) {
98
eventSet = null; // timeout
99
break;
100
}
101
/*
102
* Remove events from the event set for which
103
* there is no corresponding enabled request (
104
* this includes our internally requested events.)
105
* This never returns null
106
*/
107
eventSet = fullEventSet.userFilter();
108
if (!eventSet.isEmpty()) {
109
break;
110
}
111
}
112
113
if ((eventSet != null) && (eventSet.suspendPolicy() == JDWP.SuspendPolicy.ALL)) {
114
vm.notifySuspend();
115
}
116
117
return eventSet;
118
}
119
120
EventSet removeInternal() throws InterruptedException {
121
EventSet eventSet;
122
do {
123
// Waiting forever, so removeUnfiltered() is never null
124
eventSet = removeUnfiltered(0).internalFilter();
125
} while (eventSet == null || eventSet.isEmpty());
126
127
/*
128
* Currently, no internal events are requested with a suspend
129
* policy other than none, so we don't check for notifySuspend()
130
* here. If this changes in the future, there is much
131
* infrastructure that needs to be updated.
132
*/
133
134
return eventSet;
135
}
136
137
private TimerThread startTimerThread(long timeout) {
138
TimerThread thread = new TimerThread(timeout);
139
thread.setDaemon(true);
140
thread.start();
141
return thread;
142
}
143
144
private boolean shouldWait(TimerThread timerThread) {
145
return !closed && eventSets.isEmpty() &&
146
((timerThread == null) ? true : !timerThread.timedOut());
147
}
148
149
private EventSetImpl removeUnfiltered(long timeout)
150
throws InterruptedException {
151
EventSetImpl eventSet = null;
152
153
/*
154
* Make sure the VM has completed initialization before
155
* trying to build events.
156
*/
157
vm.waitInitCompletion();
158
159
synchronized(this) {
160
if (!eventSets.isEmpty()) {
161
/*
162
* If there's already something there, no need
163
* for anything elaborate.
164
*/
165
eventSet = (EventSetImpl)eventSets.removeFirst();
166
} else {
167
/*
168
* If a timeout was specified, create a thread to
169
* notify this one when a timeout
170
* occurs. We can't use the timed version of wait()
171
* because it is possible for multiple enqueue() calls
172
* before we see something in the eventSet queue
173
* (this is possible when multiple threads call
174
* remove() concurrently -- not a great idea, but
175
* it should be supported). Even if enqueue() did a
176
* notify() instead of notifyAll() we are not able to
177
* use a timed wait because there's no way to distinguish
178
* a timeout from a notify. That limitation implies a
179
* possible race condition between a timed out thread
180
* and a notified thread.
181
*/
182
TimerThread timerThread = null;
183
try {
184
if (timeout > 0) {
185
timerThread = startTimerThread(timeout);
186
}
187
188
while (shouldWait(timerThread)) {
189
this.wait();
190
}
191
} finally {
192
if ((timerThread != null) && !timerThread.timedOut()) {
193
timerThread.interrupt();
194
}
195
}
196
197
if (eventSets.isEmpty()) {
198
if (closed) {
199
throw new VMDisconnectedException();
200
}
201
} else {
202
eventSet = (EventSetImpl)eventSets.removeFirst();
203
}
204
}
205
}
206
207
// The build is synchronized on the event set, don't hold
208
// the queue lock.
209
if (eventSet != null) {
210
target.notifyDequeueEventSet();
211
eventSet.build();
212
}
213
return eventSet;
214
}
215
216
private class TimerThread extends Thread {
217
private boolean timedOut = false;
218
private long timeout;
219
220
TimerThread(long timeout) {
221
super(vm.threadGroupForJDI(), "JDI Event Queue Timer");
222
this.timeout = timeout;
223
}
224
225
boolean timedOut() {
226
return timedOut;
227
}
228
229
public void run() {
230
try {
231
Thread.sleep(timeout);
232
EventQueueImpl queue = EventQueueImpl.this;
233
synchronized(queue) {
234
timedOut = true;
235
queue.notifyAll();
236
}
237
} catch (InterruptedException e) {
238
// Exit without notifying
239
}
240
}
241
}
242
}
243
244