1 /* 2 * Copyright (c) 1999, 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.example.debug.bdi; 27 28 import com.sun.jdi.*; 29 import com.sun.jdi.event.*; 30 31 import java.util.*; 32 33 import com.sun.tools.example.debug.event.*; 34 35 import javax.swing.SwingUtilities; 36 37 /** 38 */ 39 class 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 (JDIListener jl : session.runtime.jdiListeners) { 86 es.notify(jl); 87 } 88 if (interrupted && !wantInterrupt) { 89 session.interrupted = false; 90 //### Catch here is a hack 91 try { 92 session.vm.resume(); 93 } catch (VMDisconnectedException ee) {} 94 } 95 if (es instanceof ThreadDeathEventSet) { 96 ThreadReference t = ((ThreadDeathEventSet)es).getThread(); 97 session.runtime.removeThreadInfo(t); 98 } 99 } 100 }); 101 } 102 103 private void finalizeEventSet(AbstractEventSet es) { 104 if (session.interrupted && !wantInterrupt) { 105 session.interrupted = false; 106 //### Catch here is a hack 107 try { 108 session.vm.resume(); 109 } catch (VMDisconnectedException ee) {} 110 } 111 if (es instanceof ThreadDeathEventSet) { 112 ThreadReference t = ((ThreadDeathEventSet)es).getThread(); 113 session.runtime.removeThreadInfo(t); 114 } 115 } 116 117 //### This is a Hack, deal with it 118 private class FirstListener implements JDIListener { 119 120 public void accessWatchpoint(AccessWatchpointEventSet e) { 121 session.runtime.validateThreadInfo(); 122 wantInterrupt = true; 123 } 124 125 public void classPrepare(ClassPrepareEventSet e) { 126 wantInterrupt = false; 127 runtime.resolve(e.getReferenceType()); 128 } 129 130 public void classUnload(ClassUnloadEventSet e) { 131 wantInterrupt = false; 132 } 133 134 public void exception(ExceptionEventSet e) { 135 wantInterrupt = true; 136 } 137 138 public void locationTrigger(LocationTriggerEventSet e) { 139 session.runtime.validateThreadInfo(); 140 wantInterrupt = true; 141 } 142 143 public void modificationWatchpoint(ModificationWatchpointEventSet e) { 144 session.runtime.validateThreadInfo(); 145 wantInterrupt = true; 146 } 147 148 public void threadDeath(ThreadDeathEventSet e) { 149 wantInterrupt = false; 150 } 151 152 public void threadStart(ThreadStartEventSet e) { 153 wantInterrupt = false; 154 } 155 156 public void vmDeath(VMDeathEventSet e) { 157 //### Should have some way to notify user 158 //### that VM died before the session ended. 159 wantInterrupt = false; 160 } 161 162 public void vmDisconnect(VMDisconnectEventSet e) { 163 //### Notify user? 164 wantInterrupt = false; 165 session.runtime.endSession(); 166 } 167 168 public void vmStart(VMStartEventSet e) { 169 //### Do we need to do anything with it? 170 wantInterrupt = false; 171 } 172 } 173 }