1 19 20 package org.netbeans.modules.debugger.jpda.util; 21 22 import com.sun.jdi.VirtualMachine; 23 import com.sun.jdi.VMDisconnectedException; 24 import com.sun.jdi.event.*; 25 import com.sun.jdi.request.EventRequest; 26 import com.sun.jdi.request.StepRequest; 27 import com.sun.jdi.ThreadReference; 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.logging.Level ; 32 import java.util.logging.Logger ; 33 import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl; 34 import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl; 35 import org.openide.ErrorManager; 36 37 61 public class Operator { 62 63 private static Logger logger = Logger.getLogger("org.netbeans.modules.debugger.jpda.jdievents"); 65 private Thread thread; 66 private boolean breakpointsDisabled; 67 private List <EventSet> staledEvents = new ArrayList <EventSet>(); 68 private List <EventRequest> staledRequests = new ArrayList <EventRequest>(); 69 private boolean stop; 70 71 82 public Operator ( 83 VirtualMachine virtualMachine, 84 final JPDADebuggerImpl debugger, 85 Executor starter, 86 Runnable finalizer, 87 final Object resumeLock 88 ) { 89 EventQueue eventQueue = virtualMachine.eventQueue (); 90 if (eventQueue == null) 91 throw new NullPointerException (); 92 final Object [] params = new Object [] {eventQueue, starter, finalizer}; 93 thread = new Thread (new Runnable () { 94 public void run () { 95 EventQueue eventQueue = (EventQueue) params [0]; 96 Executor starter = (Executor) params [1]; 97 Runnable finalizer = (Runnable ) params [2]; 98 params [0] = null; 99 params [1] = null; 100 params [2] = null; 101 boolean processStaledEvents = false; 102 103 try { 104 for (;;) { 105 EventSet eventSet = null; 106 if (processStaledEvents) { 107 synchronized (Operator.this) { 108 if (staledEvents.size() == 0) { 109 processStaledEvents = false; 110 } else { 111 eventSet = staledEvents.remove(0); 112 while (staledRequests.size() > 0) { 113 EventRequest request = staledRequests.remove(0); 114 request.virtualMachine().eventRequestManager().deleteEventRequest(request); 115 } 116 } 118 } 119 } 120 if (eventSet == null) { 121 try { 122 eventSet = eventQueue.remove (); 123 if (logger.isLoggable(Level.FINE)) { 124 logger.fine("HAVE EVENT(s) in the Queue: "+eventSet); 125 } 126 } catch (InterruptedException iexc) { 127 synchronized (Operator.this) { 128 if (stop) { 129 break; 130 } 131 } 132 processStaledEvents = true; 133 continue; 134 } 135 } 136 synchronized (Operator.this) { 137 if (breakpointsDisabled) { 138 if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL) { 139 staledEvents.add(eventSet); 140 eventSet.resume(); 141 if (logger.isLoggable(Level.FINE)) { 142 logger.fine("RESUMING "+eventSet); 143 } 144 } 145 continue; 146 } 147 } 148 boolean resume = true, startEventOnly = true; 149 int suspendPolicy = eventSet.suspendPolicy(); 150 boolean suspendedAll = suspendPolicy == EventRequest.SUSPEND_ALL; 151 JPDAThreadImpl suspendedThread = null; 152 if (suspendedAll) debugger.notifySuspendAll(); 153 if (suspendPolicy == EventRequest.SUSPEND_EVENT_THREAD) { 154 EventIterator i = eventSet.eventIterator (); 155 ThreadReference tref = null; 156 while (i.hasNext ()) { 157 Event e = i.nextEvent (); 158 if (e instanceof LocatableEvent) { 159 tref = ((LocatableEvent) e).thread(); 160 break; 161 } 162 if (e instanceof ClassPrepareEvent) { 163 tref = ((ClassPrepareEvent) e).thread(); 164 } 165 if (e instanceof ThreadStartEvent) { 166 tref = ((ThreadStartEvent) e).thread(); 167 } 168 if (e instanceof ThreadDeathEvent) { 169 tref = ((ThreadDeathEvent) e).thread(); 170 } 171 } 172 if (tref != null) { 173 suspendedThread = ((JPDAThreadImpl) debugger.getThread(tref)); 174 suspendedThread.notifySuspended(); 175 } 176 } 177 if (logger.isLoggable(Level.FINE)) { 178 switch (suspendPolicy) { 179 case EventRequest.SUSPEND_ALL: 180 logger.fine("JDI new events (suspend all)============================================="); 181 break; 182 case EventRequest.SUSPEND_EVENT_THREAD: 183 logger.fine("JDI new events (suspend one)============================================="); 184 break; 185 case EventRequest.SUSPEND_NONE: 186 logger.fine("JDI new events (suspend none)============================================="); 187 break; 188 default: 189 logger.fine("JDI new events (?????)============================================="); 190 break; 191 } 192 } 193 EventIterator i = eventSet.eventIterator (); 194 while (i.hasNext ()) { 195 Event e = i.nextEvent (); 196 if ((e instanceof VMDeathEvent) || 197 (e instanceof VMDisconnectEvent) 198 ) { 199 200 if (logger.isLoggable(Level.FINE)) { 201 printEvent (e, null); 202 } 203 synchronized (Operator.this) { 204 stop = true; 205 } 206 if (finalizer != null) finalizer.run (); 208 finalizer = null; 211 eventQueue = null; 212 starter = null; 213 return; 214 } 215 216 if ((e instanceof VMStartEvent) && (starter != null)) { 217 resume = resume & starter.exec (e); 218 if (logger.isLoggable(Level.FINE)) { 220 printEvent (e, null); 221 } 222 continue; 223 } 224 Executor exec = null; 225 if (e.request () == null) { 226 if (logger.isLoggable(Level.FINE)) { 227 logger.fine("EVENT: " + e + " REQUEST: null"); } 229 } else 230 exec = (Executor) e.request ().getProperty ("executor"); 231 232 if (logger.isLoggable(Level.FINE)) { 233 printEvent (e, exec); 234 } 235 236 if (exec != null) 238 try { 239 startEventOnly = false; 240 resume = resume & exec.exec (e); 241 } catch (VMDisconnectedException exc) { 242 synchronized (Operator.this) { 244 stop = true; 245 } 246 if (finalizer != null) finalizer.run (); 247 return; 250 } catch (Exception ex) { 251 ErrorManager.getDefault().notify(ex); 252 } 253 } if (logger.isLoggable(Level.FINE)) { 256 logger.fine("JDI events dispatched (resume " + (resume && (!startEventOnly)) + ")"); 257 logger.fine(" resume = "+resume+", startEventOnly = "+startEventOnly); 258 } 259 if (resume && (!startEventOnly)) { 260 if (suspendedAll) { 261 debugger.notifyToBeResumedAll(); 263 } 264 if (suspendedThread != null) { 265 suspendedThread.notifyToBeResumed(); 266 } 267 synchronized (resumeLock) { 268 eventSet.resume (); 269 } 270 } 271 if (!resume) { synchronized (resumeLock) { 273 List <ThreadReference> threads = eventSet.virtualMachine().allThreads(); 274 for (ThreadReference t : threads) { 275 while (t.suspendCount() > 1) t.resume(); 276 } 277 } 278 } 279 } } catch (VMDisconnectedException e) { 281 } catch (Exception e) { 283 ErrorManager.getDefault().notify(e); 284 } 285 if (finalizer != null) finalizer.run (); 286 finalizer = null; 288 eventQueue = null; 289 starter = null; 290 } 291 }, "Debugger operator thread"); } 293 294 297 public void start () { 298 thread.start (); 299 } 300 301 311 public synchronized void register (EventRequest req, Executor e) { 312 req.putProperty ("executor", e); if (staledEvents.size() > 0 && req instanceof StepRequest) { 314 boolean addAsStaled = false; 315 for (Iterator <EventSet> it = staledEvents.iterator(); it.hasNext(); ) { 316 EventSet evSet = it.next(); 317 for (Iterator <Event> itSet = evSet.iterator(); itSet.hasNext(); ) { 318 Event ev = itSet.next(); 319 EventRequest evReq = ev.request(); 320 if (!(evReq instanceof StepRequest)) { 321 addAsStaled = true; 322 break; 323 } else { 324 ThreadReference evThread = ((StepRequest) evReq).thread(); 325 ThreadReference reqThread = ((StepRequest) req).thread(); 326 if (reqThread.equals(evThread)) { 327 addAsStaled = true; 328 break; 329 } 330 } 331 } 332 if (addAsStaled) break; 333 } 334 if (addAsStaled) { 337 staledRequests.add(req); 338 } 339 }; 340 } 341 342 348 public synchronized void unregister (EventRequest req) { 349 req.putProperty ("executor", null); staledRequests.remove(req); 351 } 352 353 356 public void stop() { 357 synchronized (this) { 358 staledRequests.clear(); 359 staledEvents.clear(); 360 if (stop) return ; stop = true; 362 } 363 thread.interrupt(); 364 } 365 366 370 public synchronized void breakpointsDisabled() { 371 breakpointsDisabled = true; 372 } 373 374 377 public synchronized void breakpointsEnabled() { 378 breakpointsDisabled = false; 379 } 380 381 public boolean flushStaledEvents() { 382 boolean areStaledEvents; 383 synchronized (this) { 384 areStaledEvents = staledEvents.size() > 0; 385 if (areStaledEvents) { 386 thread.interrupt(); 387 } 388 } 389 return areStaledEvents; 390 } 391 392 private void printEvent (Event e, Executor exec) { 393 try { 394 if (e instanceof ClassPrepareEvent) { 395 logger.fine("JDI EVENT: ClassPrepareEvent " + ((ClassPrepareEvent) e).referenceType ()); } else 397 if (e instanceof ClassUnloadEvent) { 398 logger.fine("JDI EVENT: ClassUnloadEvent " + ((ClassUnloadEvent) e).className ()); } else 400 if (e instanceof ThreadStartEvent) { 401 try { 402 logger.fine("JDI EVENT: ThreadStartEvent " + ((ThreadStartEvent) e).thread ()); } catch (Exception ex) { 404 logger.fine("JDI EVENT: ThreadStartEvent1 " + e); } 406 } else 407 if (e instanceof ThreadDeathEvent) { 408 try { 409 logger.fine("JDI EVENT: ThreadDeathEvent " + ((ThreadDeathEvent) e).thread ()); } catch (Exception ex) { 411 logger.fine("JDI EVENT: ThreadDeathEvent1 " + e); } 413 } else 414 if (e instanceof MethodEntryEvent) { 415 try { 416 logger.fine("JDI EVENT: MethodEntryEvent " + e); 417 } catch (Exception ex) { 418 logger.fine("JDI EVENT: MethodEntryEvent " + e); 419 } 420 } else 421 if (e instanceof BreakpointEvent) { 422 logger.fine("JDI EVENT: BreakpointEvent " + ((BreakpointEvent) e).thread () + " : " + ((BreakpointEvent) e).location ()); } else 424 if (e instanceof StepEvent) { 425 logger.fine("JDI EVENT: StepEvent " + ((StepEvent) e).thread () + " : " + ((StepEvent) e).location ()); } else 427 logger.fine("JDI EVENT: " + e + " : " + exec); } catch (Exception ex) { 429 } 430 } 431 } 432 | Popular Tags |