blob: 2bd45c2fc387e47a7ae0149da0787fd1026ddf0b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.example.debug.bdi;
27
28import com.sun.jdi.*;
29import com.sun.jdi.event.*;
30
31import java.util.*;
32
33import com.sun.tools.example.debug.event.*;
34
35import javax.swing.SwingUtilities;
36
37/**
38 */
39class JDIEventSource extends Thread {
40
41 private /*final*/ EventQueue queue;
42 private /*final*/ Session session;
43 private /*final*/ ExecutionManager runtime;
44 private final JDIListener firstListener = new FirstListener();
45
46 private boolean wantInterrupt; //### Hack
47
48 /**
49 * Create event source.
50 */
51 JDIEventSource(Session session) {
52 super("JDI Event Set Dispatcher");
53 this.session = session;
54 this.runtime = session.runtime;
55 this.queue = session.vm.eventQueue();
56 }
57
58 public void run() {
59 try {
60 runLoop();
61 } catch (Exception exc) {
62 //### Do something different for InterruptedException???
63 // just exit
64 }
65 session.running = false;
66 }
67
68 private void runLoop() throws InterruptedException {
69 AbstractEventSet es;
70 do {
71 EventSet jdiEventSet = queue.remove();
72 es = AbstractEventSet.toSpecificEventSet(jdiEventSet);
73 session.interrupted = es.suspendedAll();
74 dispatchEventSet(es);
75 } while(!(es instanceof VMDisconnectEventSet));
76 }
77
78 //### Gross foul hackery!
79 private void dispatchEventSet(final AbstractEventSet es) {
80 SwingUtilities.invokeLater(new Runnable() {
81 public void run() {
82 boolean interrupted = es.suspendedAll();
83 es.notify(firstListener);
84 boolean wantInterrupt = JDIEventSource.this.wantInterrupt;
85 for (Iterator it = session.runtime.jdiListeners.iterator();
86 it.hasNext(); ) {
87 JDIListener jl = (JDIListener)it.next();
88 es.notify(jl);
89 }
90 if (interrupted && !wantInterrupt) {
91 session.interrupted = false;
92 //### Catch here is a hack
93 try {
94 session.vm.resume();
95 } catch (VMDisconnectedException ee) {}
96 }
97 if (es instanceof ThreadDeathEventSet) {
98 ThreadReference t = ((ThreadDeathEventSet)es).getThread();
99 session.runtime.removeThreadInfo(t);
100 }
101 }
102 });
103 }
104
105 private void finalizeEventSet(AbstractEventSet es) {
106 if (session.interrupted && !wantInterrupt) {
107 session.interrupted = false;
108 //### Catch here is a hack
109 try {
110 session.vm.resume();
111 } catch (VMDisconnectedException ee) {}
112 }
113 if (es instanceof ThreadDeathEventSet) {
114 ThreadReference t = ((ThreadDeathEventSet)es).getThread();
115 session.runtime.removeThreadInfo(t);
116 }
117 }
118
119 //### This is a Hack, deal with it
120 private class FirstListener implements JDIListener {
121
122 public void accessWatchpoint(AccessWatchpointEventSet e) {
123 session.runtime.validateThreadInfo();
124 wantInterrupt = true;
125 }
126
127 public void classPrepare(ClassPrepareEventSet e) {
128 wantInterrupt = false;
129 runtime.resolve(e.getReferenceType());
130 }
131
132 public void classUnload(ClassUnloadEventSet e) {
133 wantInterrupt = false;
134 }
135
136 public void exception(ExceptionEventSet e) {
137 wantInterrupt = true;
138 }
139
140 public void locationTrigger(LocationTriggerEventSet e) {
141 session.runtime.validateThreadInfo();
142 wantInterrupt = true;
143 }
144
145 public void modificationWatchpoint(ModificationWatchpointEventSet e) {
146 session.runtime.validateThreadInfo();
147 wantInterrupt = true;
148 }
149
150 public void threadDeath(ThreadDeathEventSet e) {
151 wantInterrupt = false;
152 }
153
154 public void threadStart(ThreadStartEventSet e) {
155 wantInterrupt = false;
156 }
157
158 public void vmDeath(VMDeathEventSet e) {
159 //### Should have some way to notify user
160 //### that VM died before the session ended.
161 wantInterrupt = false;
162 }
163
164 public void vmDisconnect(VMDisconnectEventSet e) {
165 //### Notify user?
166 wantInterrupt = false;
167 session.runtime.endSession();
168 }
169
170 public void vmStart(VMStartEventSet e) {
171 //### Do we need to do anything with it?
172 wantInterrupt = false;
173 }
174 }
175}