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/example/debug/tty/EventHandler.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/example/debug/tty/EventHandler.java+277−0
@@ -0,0 +1,277 @@
1/*
2 * Copyright (c) 1998, 2008, 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.example.debug.tty;
27
28import com.sun.jdi.*;
29import com.sun.jdi.event.*;
30import com.sun.jdi.request.EventRequest;
31
32public class EventHandler implements Runnable {
33
34 EventNotifier notifier;
35 Thread thread;
36 volatile boolean connected = true;
37 boolean completed = false;
38 String shutdownMessageKey;
39 boolean stopOnVMStart;
40
41 EventHandler(EventNotifier notifier, boolean stopOnVMStart) {
42 this.notifier = notifier;
43 this.stopOnVMStart = stopOnVMStart;
44 this.thread = new Thread(this, "event-handler");
45 this.thread.start();
46 }
47
48 synchronized void shutdown() {
49 connected = false; // force run() loop termination
50 thread.interrupt();
51 while (!completed) {
52 try {wait();} catch (InterruptedException exc) {}
53 }
54 }
55
56 @Override
57 public void run() {
58 EventQueue queue = Env.vm().eventQueue();
59 while (connected) {
60 try {
61 EventSet eventSet = queue.remove();
62 boolean resumeStoppedApp = false;
63 EventIterator it = eventSet.eventIterator();
64 while (it.hasNext()) {
65 resumeStoppedApp |= !handleEvent(it.nextEvent());
66 }
67
68 if (resumeStoppedApp) {
69 eventSet.resume();
70 } else if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL) {
71 setCurrentThread(eventSet);
72 notifier.vmInterrupted();
73 }
74 } catch (InterruptedException exc) {
75 // Do nothing. Any changes will be seen at top of loop.
76 } catch (VMDisconnectedException discExc) {
77 handleDisconnectedException();
78 break;
79 }
80 }
81 synchronized (this) {
82 completed = true;
83 notifyAll();
84 }
85 }
86
87 private boolean handleEvent(Event event) {
88 notifier.receivedEvent(event);
89
90 if (event instanceof ExceptionEvent) {
91 return exceptionEvent(event);
92 } else if (event instanceof BreakpointEvent) {
93 return breakpointEvent(event);
94 } else if (event instanceof WatchpointEvent) {
95 return fieldWatchEvent(event);
96 } else if (event instanceof StepEvent) {
97 return stepEvent(event);
98 } else if (event instanceof MethodEntryEvent) {
99 return methodEntryEvent(event);
100 } else if (event instanceof MethodExitEvent) {
101 return methodExitEvent(event);
102 } else if (event instanceof ClassPrepareEvent) {
103 return classPrepareEvent(event);
104 } else if (event instanceof ClassUnloadEvent) {
105 return classUnloadEvent(event);
106 } else if (event instanceof ThreadStartEvent) {
107 return threadStartEvent(event);
108 } else if (event instanceof ThreadDeathEvent) {
109 return threadDeathEvent(event);
110 } else if (event instanceof VMStartEvent) {
111 return vmStartEvent(event);
112 } else {
113 return handleExitEvent(event);
114 }
115 }
116
117 private boolean vmDied = false;
118 private boolean handleExitEvent(Event event) {
119 if (event instanceof VMDeathEvent) {
120 vmDied = true;
121 return vmDeathEvent(event);
122 } else if (event instanceof VMDisconnectEvent) {
123 connected = false;
124 if (!vmDied) {
125 vmDisconnectEvent(event);
126 }
127 Env.shutdown(shutdownMessageKey);
128 return false;
129 } else {
130 throw new InternalError(MessageOutput.format("Unexpected event type",
131 new Object[] {event.getClass()}));
132 }
133 }
134
135 synchronized void handleDisconnectedException() {
136 /*
137 * A VMDisconnectedException has happened while dealing with
138 * another event. We need to flush the event queue, dealing only
139 * with exit events (VMDeath, VMDisconnect) so that we terminate
140 * correctly.
141 */
142 EventQueue queue = Env.vm().eventQueue();
143 while (connected) {
144 try {
145 EventSet eventSet = queue.remove();
146 EventIterator iter = eventSet.eventIterator();
147 while (iter.hasNext()) {
148 handleExitEvent(iter.next());
149 }
150 } catch (InterruptedException exc) {
151 // ignore
152 } catch (InternalError exc) {
153 // ignore
154 }
155 }
156 }
157
158 private ThreadReference eventThread(Event event) {
159 if (event instanceof ClassPrepareEvent) {
160 return ((ClassPrepareEvent)event).thread();
161 } else if (event instanceof LocatableEvent) {
162 return ((LocatableEvent)event).thread();
163 } else if (event instanceof ThreadStartEvent) {
164 return ((ThreadStartEvent)event).thread();
165 } else if (event instanceof ThreadDeathEvent) {
166 return ((ThreadDeathEvent)event).thread();
167 } else if (event instanceof VMStartEvent) {
168 return ((VMStartEvent)event).thread();
169 } else {
170 return null;
171 }
172 }
173
174 private void setCurrentThread(EventSet set) {
175 ThreadReference thread;
176 if (set.size() > 0) {
177 /*
178 * If any event in the set has a thread associated with it,
179 * they all will, so just grab the first one.
180 */
181 Event event = set.iterator().next(); // Is there a better way?
182 thread = eventThread(event);
183 } else {
184 thread = null;
185 }
186 setCurrentThread(thread);
187 }
188
189 private void setCurrentThread(ThreadReference thread) {
190 ThreadInfo.invalidateAll();
191 ThreadInfo.setCurrentThread(thread);
192 }
193
194 private boolean vmStartEvent(Event event) {
195 VMStartEvent se = (VMStartEvent)event;
196 notifier.vmStartEvent(se);
197 return stopOnVMStart;
198 }
199
200 private boolean breakpointEvent(Event event) {
201 BreakpointEvent be = (BreakpointEvent)event;
202 notifier.breakpointEvent(be);
203 return true;
204 }
205
206 private boolean methodEntryEvent(Event event) {
207 MethodEntryEvent me = (MethodEntryEvent)event;
208 notifier.methodEntryEvent(me);
209 return true;
210 }
211
212 private boolean methodExitEvent(Event event) {
213 MethodExitEvent me = (MethodExitEvent)event;
214 return notifier.methodExitEvent(me);
215 }
216
217 private boolean fieldWatchEvent(Event event) {
218 WatchpointEvent fwe = (WatchpointEvent)event;
219 notifier.fieldWatchEvent(fwe);
220 return true;
221 }
222
223 private boolean stepEvent(Event event) {
224 StepEvent se = (StepEvent)event;
225 notifier.stepEvent(se);
226 return true;
227 }
228
229 private boolean classPrepareEvent(Event event) {
230 ClassPrepareEvent cle = (ClassPrepareEvent)event;
231 notifier.classPrepareEvent(cle);
232
233 if (!Env.specList.resolve(cle)) {
234 MessageOutput.lnprint("Stopping due to deferred breakpoint errors.");
235 return true;
236 } else {
237 return false;
238 }
239 }
240
241 private boolean classUnloadEvent(Event event) {
242 ClassUnloadEvent cue = (ClassUnloadEvent)event;
243 notifier.classUnloadEvent(cue);
244 return false;
245 }
246
247 private boolean exceptionEvent(Event event) {
248 ExceptionEvent ee = (ExceptionEvent)event;
249 notifier.exceptionEvent(ee);
250 return true;
251 }
252
253 private boolean threadDeathEvent(Event event) {
254 ThreadDeathEvent tee = (ThreadDeathEvent)event;
255 ThreadInfo.removeThread(tee.thread());
256 return false;
257 }
258
259 private boolean threadStartEvent(Event event) {
260 ThreadStartEvent tse = (ThreadStartEvent)event;
261 ThreadInfo.addThread(tse.thread());
262 notifier.threadStartEvent(tse);
263 return false;
264 }
265
266 public boolean vmDeathEvent(Event event) {
267 shutdownMessageKey = "The application exited";
268 notifier.vmDeathEvent((VMDeathEvent)event);
269 return false;
270 }
271
272 public boolean vmDisconnectEvent(Event event) {
273 shutdownMessageKey = "The application has been disconnected";
274 notifier.vmDisconnectEvent((VMDisconnectEvent)event);
275 return false;
276 }
277}