History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/jdi/EventQueueImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/jdi/EventQueueImpl.java+242−0
@@ -0,0 +1,242 @@
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
26package com.sun.tools.jdi;
27
28import com.sun.jdi.*;
29import com.sun.jdi.event.EventQueue;
30import com.sun.jdi.event.EventSet;
31
32import java.util.*;
33
34public 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}