1 11 package org.eclipse.debug.internal.ui.views.launch; 12 13 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Map ; 17 import java.util.Set ; 18 19 import org.eclipse.debug.core.DebugEvent; 20 import org.eclipse.debug.core.DebugException; 21 import org.eclipse.debug.core.DebugPlugin; 22 import org.eclipse.debug.core.ILaunch; 23 import org.eclipse.debug.core.ILaunchManager; 24 import org.eclipse.debug.core.ILaunchesListener2; 25 import org.eclipse.debug.core.model.IDebugElement; 26 import org.eclipse.debug.core.model.IDebugTarget; 27 import org.eclipse.debug.core.model.IProcess; 28 import org.eclipse.debug.core.model.IStackFrame; 29 import org.eclipse.debug.core.model.IThread; 30 import org.eclipse.debug.internal.ui.DebugUIPlugin; 31 import org.eclipse.debug.internal.ui.views.AbstractDebugEventHandler; 32 import org.eclipse.jface.viewers.IStructuredSelection; 33 import org.eclipse.jface.viewers.ITreeContentProvider; 34 import org.eclipse.jface.viewers.StructuredSelection; 35 36 39 public class LaunchViewEventHandler extends AbstractDebugEventHandler implements ILaunchesListener2 { 40 44 private ThreadTimer fThreadTimer= new ThreadTimer(); 45 46 49 private IStackFrame fLastStackFrame = null; 50 51 56 public LaunchViewEventHandler(LaunchView view) { 57 super(view); 58 DebugPlugin plugin= DebugPlugin.getDefault(); 59 plugin.getLaunchManager().addLaunchListener(this); 60 } 61 62 63 66 protected DebugEvent[] filterEvents(DebugEvent[] events) { 67 if (events.length > 0) { 68 DebugEvent event = events[0]; 69 Object source = event.getSource(); 70 ILaunch launch = null; 71 if (source instanceof IDebugElement) { 72 launch = ((IDebugElement)source).getLaunch(); 73 } else if (source instanceof IProcess) { 74 launch = ((IProcess)source).getLaunch(); 75 } 76 if (launch != null && DebugPlugin.getDefault().getLaunchManager().isRegistered(launch)) { 79 return events; 80 } 81 return EMPTY_EVENT_SET; 82 } 83 return events; 84 } 85 86 92 private Object getParent(Object element) { 93 return ((ITreeContentProvider)getTreeViewer().getContentProvider()).getParent(element); 94 } 95 96 99 protected void doHandleDebugEvents(DebugEvent[] events, Object data) { 100 fThreadTimer.handleDebugEvents(events); 101 Object suspendee = null; 102 for (int i = 0; i < events.length; i++) { 103 DebugEvent event = events[i]; 104 Object source= event.getSource(); 105 switch (event.getKind()) { 106 case DebugEvent.CREATE : 107 if (source instanceof IThread) { 108 insert(source); 109 } else { 110 Object parent = getParent(source); 111 if (parent != null) { 112 refresh(parent); 113 } 114 if (source instanceof IDebugTarget | source instanceof IProcess) { 115 getLaunchView().autoExpand(source, true); 116 } 117 } 118 break; 119 case DebugEvent.TERMINATE : 120 clearSourceSelection(source); 121 if (source instanceof IThread) { 122 fThreadTimer.getTimedOutThreads().remove(source); 123 remove(source); 124 } else { 125 Object parent = getParent(source); 126 if (parent != null) { 127 refresh(parent); 128 } 129 } 130 break; 131 case DebugEvent.RESUME : 132 doHandleResumeEvent(event, source, data); 133 break; 134 case DebugEvent.SUSPEND : 135 if (suspendee == null || !suspendee.equals(source)) { 136 doHandleSuspendEvent(source, event, data); 137 suspendee = source; 138 } 139 break; 140 case DebugEvent.CHANGE : 141 Object element = null; 142 IStructuredSelection selection = getLaunchViewer().getDeferredSelection(); 143 if (selection == null) { 144 selection = (IStructuredSelection) getLaunchViewer().getSelection(); 145 } 146 147 element = selection.getFirstElement(); 148 IStackFrame lastFrame = null; 149 if (element instanceof IStackFrame) { 150 lastFrame = (IStackFrame) element; 151 } 152 if (source instanceof IStackFrame) { 153 if (source.equals(lastFrame)) { 154 getLaunchView().setStackFrame(null); 155 getLaunchView().autoExpand(lastFrame, true); 156 } 157 } 158 if (event.getDetail() == DebugEvent.STATE) { 159 labelChanged(source); 160 } else { 161 refresh(source); 163 } 164 if (lastFrame != null && source instanceof IThread) { 165 if (lastFrame.getThread().equals(source)) { 166 getLaunchView().autoExpand(lastFrame, true); 167 } 168 } 169 break; 170 } 171 } 172 } 173 174 177 protected void doHandleResumeEvent(DebugEvent event, Object source, Object data) { 178 if (!event.isEvaluation()) { 179 clearSourceSelection(source); 180 } 181 if (event.isEvaluation() || event.isStepStart()) { 182 IThread thread= getThread(source); 185 if (thread != null) { 186 fThreadTimer.startTimer(thread); 187 } 188 return; 189 } 190 refresh(source); 191 if (source instanceof IThread) { 192 if (data instanceof IStackFrame) { 193 selectAndReveal(data); 194 return; 195 } 196 selectAndReveal(source); 197 } 198 } 199 200 206 protected void updateRunningThread(IThread thread) { 207 labelChanged(thread); 208 getLaunchViewer().updateStackFrameImages(thread); 209 clearSourceSelection(thread); 210 } 211 212 protected void doHandleSuspendEvent(Object element, DebugEvent event, Object data) { 213 IThread thread= getThread(element); 214 if (thread != null) { 215 fThreadTimer.stopTimer(thread); 216 } 217 218 boolean wasTimedOut= fThreadTimer.getTimedOutThreads().remove(thread); 219 if (event.isEvaluation() && ((event.getDetail() & DebugEvent.EVALUATION_IMPLICIT) != 0)) { 220 if (thread != null && !wasTimedOut) { 221 return; 223 } 224 } 225 if (element instanceof IThread) { 226 doHandleSuspendThreadEvent((IThread)element, event, wasTimedOut, data); 227 return; 228 } 229 refresh(element); 230 } 231 232 235 protected void doHandleSuspendThreadEvent(IThread thread, DebugEvent event, boolean wasTimedOut, Object data) { 236 if (!thread.isSuspended() || !isAvailable()) { 238 return; 239 } 240 241 boolean evaluationEvent = event.isEvaluation(); 243 244 IStackFrame frame = null; 246 if (data instanceof IStackFrame) { 247 frame = (IStackFrame) data; 248 } 249 250 if (frame != null && frame.equals(fLastStackFrame)) { 253 if (wasTimedOut) { 254 getLaunchViewer().updateStackFrameImages(thread); 255 } 256 getLaunchViewer().update(new Object [] {thread, frame}, null); 257 if (!evaluationEvent) { 258 getLaunchViewer().deferExpansion(thread); 259 getLaunchViewer().deferSelection(new StructuredSelection(frame)); 260 } else if (wasTimedOut) { 261 getLaunchView().showEditorForCurrentSelection(); 262 } 263 return; 264 } 265 266 if (frame == null) { 267 fLastStackFrame = null; 269 refresh(thread); 270 getLaunchView().autoExpand(thread, !evaluationEvent); 271 } else { 272 fLastStackFrame = frame; 273 refresh(thread); 276 getLaunchView().autoExpand(frame, !evaluationEvent); 277 } 278 } 279 280 283 protected void updateForDebugEvents(DebugEvent[] events, Object data) { 284 super.updateForDebugEvents(events, data); 285 if (isViewVisible()) { 286 return; 287 } 288 doHandleDebugEvents(events, data); 289 } 290 291 294 public void dispose() { 295 super.dispose(); 296 fThreadTimer.stop(); 297 DebugPlugin plugin= DebugPlugin.getDefault(); 298 plugin.getLaunchManager().removeLaunchListener(this); 299 } 300 301 304 private void clearSourceSelection(Object source) { 305 if (getViewer() != null) { 306 getLaunchView().clearSourceSelection(source); 307 } 308 } 309 310 315 protected LaunchViewer getLaunchViewer() { 316 return (LaunchViewer)getViewer(); 317 } 318 319 324 protected LaunchView getLaunchView() { 325 return (LaunchView)getView(); 326 } 327 328 private IThread getThread(Object element) { 329 IThread thread = null; 330 if (element instanceof IThread) { 331 thread = (IThread) element; 332 } else if (element instanceof IStackFrame) { 333 thread = ((IStackFrame)element).getThread(); 334 } 335 return thread; 336 } 337 338 class ThreadTimer { 339 340 private Thread fThread; 341 344 private long TIMEOUT= 500; 345 349 private long timeEmpty= 0; 350 354 private long MAX_TIME_EMPTY= 3000; 355 private boolean fStopped= false; 356 private Object fLock= new Object (); 357 358 364 HashMap fStopTimes= new HashMap (); 365 368 HashSet fTimedOutThreads= new HashSet (); 369 370 public Set getTimedOutThreads() { 371 return fTimedOutThreads; 372 } 373 374 378 public void handleDebugEvents(DebugEvent[] events) { 379 if (fStopped) { 380 return; 381 } 382 DebugEvent event; 383 for (int i= 0, numEvents= events.length; i < numEvents; i++) { 384 event= events[i]; 385 if (event.getKind() == DebugEvent.TERMINATE && event.getSource() instanceof IDebugTarget) { 386 ILaunch[] launches= DebugPlugin.getDefault().getLaunchManager().getLaunches(); 387 for (int j= 0; j < launches.length; j++) { 389 IDebugTarget[] targets= launches[j].getDebugTargets(); 390 for (int k = 0; k < targets.length; k++) { 391 IDebugTarget target = targets[k]; 392 if (target != null && !target.isDisconnected() && !target.isTerminated()) { 393 return; 394 } 395 } 396 } 397 stop(); 399 return; 400 } 401 } 402 } 403 404 public void startTimer(IThread thread) { 405 synchronized (fLock) { 406 fStopTimes.put(thread, new Long (System.currentTimeMillis() + TIMEOUT)); 407 if (fThread == null) { 408 startThread(); 409 } 410 } 411 } 412 413 public void stop() { 414 synchronized (fLock) { 415 fStopped= true; 416 fThread= null; 417 fStopTimes.clear(); 418 } 419 } 420 421 public void stopTimer(IThread thread) { 422 synchronized (fLock) { 423 fStopTimes.remove(thread); 424 } 425 } 426 427 private void startThread() { 428 fThread= new Thread (new Runnable () { 429 public void run() { 430 fStopped= false; 431 while (!fStopped) { 432 checkTimers(); 433 } 434 435 } 436 }, "Thread timer"); fThread.setDaemon(true); 438 fThread.start(); 439 } 440 441 private void checkTimers() { 442 long timeToWait= TIMEOUT; 443 Map.Entry [] entries; 444 synchronized (fLock) { 445 if (fStopTimes.size() == 0) { 446 if (timeEmpty == 0) { 447 timeEmpty= System.currentTimeMillis(); 448 } else if (System.currentTimeMillis() - timeEmpty > MAX_TIME_EMPTY) { 449 stop(); 450 return; 451 } 452 } else { 453 timeEmpty= 0; 454 } 455 entries= (Map.Entry [])fStopTimes.entrySet().toArray(new Map.Entry [0]); 456 } 457 long stopTime, currentTime= System.currentTimeMillis(); 458 Long entryValue; 459 Map.Entry entry= null; 460 for (int i= 0, numEntries= entries.length; i < numEntries; i++) { 461 entry= entries[i]; 462 entryValue= (Long )entry.getValue(); 463 if (entryValue == null) { 464 continue; 465 } 466 stopTime= entryValue.longValue(); 467 if (stopTime <= currentTime) { 468 final IThread thread= (IThread)entry.getKey(); 472 fStopTimes.remove(thread); 473 getView().asyncExec(new Runnable () { 474 public void run() { 475 fTimedOutThreads.add(thread); 476 updateRunningThread(thread); 477 } 478 }); 479 } else { 480 timeToWait= Math.min(timeToWait, stopTime - currentTime); 481 } 482 } 483 try { 484 Thread.sleep(timeToWait); 485 } catch (InterruptedException e) { 486 } 487 } 488 } 489 490 493 public void launchesAdded(final ILaunch[] launches) { 494 Runnable r= new Runnable () { 495 public void run() { 496 if (isAvailable()) { 497 if (launches.length == 1) { 498 insert(launches[0]); 499 } else { 500 refresh(); 501 } 502 for (int i = 0; i < launches.length; i++) { 503 if (launches[i].hasChildren()) { 504 getLaunchView().autoExpand(launches[i], false); 505 } 506 } 507 508 } 509 } 510 }; 511 512 getView().syncExec(r); 513 } 514 515 518 public void launchesChanged(final ILaunch[] launches) { 519 Runnable r= new Runnable () { 520 public void run() { 521 if (isAvailable()) { 522 if (launches.length == 1) { 523 refresh(launches[0]); 524 } else { 525 refresh(); 526 } 527 for (int i = 0; i < launches.length; i++) { 528 if (launches[i].hasChildren()) { 529 getLaunchView().autoExpand(launches[i], false); 530 } 531 } 532 } 533 } 534 }; 535 536 getView().asyncExec(r); 537 } 538 539 542 public void launchesRemoved(final ILaunch[] launches) { 543 Runnable r= new Runnable () { 544 public void run() { 545 if (isAvailable()) { 546 if (launches.length == 1) { 547 remove(launches[0]); 548 } else { 549 refresh(); 550 } 551 552 getLaunchView().cleanupLaunches(launches); 553 554 ILaunchManager lm= DebugPlugin.getDefault().getLaunchManager(); 555 IDebugTarget[] targets= lm.getDebugTargets(); 556 if (targets.length > 0) { 557 IDebugTarget target= targets[targets.length - 1]; 558 try { 559 IThread[] threads= target.getThreads(); 560 for (int i=0; i < threads.length; i++) { 561 if (threads[i].isSuspended()) { 562 IStackFrame topStackFrame = threads[i].getTopStackFrame(); 563 if (topStackFrame != null) { 564 getLaunchView().autoExpand(topStackFrame, true); 565 } 566 return; 567 } 568 } 569 } catch (DebugException de) { 570 DebugUIPlugin.log(de); 571 } 572 573 getLaunchView().autoExpand(target.getLaunch(), true); 574 } 575 } 576 } 577 }; 578 579 getView().asyncExec(r); 580 } 581 582 583 586 public void launchesTerminated(final ILaunch[] launches) { 587 if (fLastStackFrame != null) { 588 ILaunch launch= fLastStackFrame.getLaunch(); 589 for (int i = 0; i < launches.length; i++) { 590 ILaunch terminatedLaunch = launches[i]; 591 if (terminatedLaunch.equals(launch)) { 592 fLastStackFrame= null; 593 } 594 } 595 } 596 Runnable r= new Runnable () { 597 public void run() { 598 getLaunchView().cleanupLaunches(launches); 599 } 600 }; 601 getView().asyncExec(r); 602 } 603 604 607 protected DebugEvent[] doPreprocessEvents(DebugEvent[] events) { 608 for (int i = 0; i < events.length; i++) { 609 DebugEvent event = events[i]; 610 Object source = event.getSource(); 611 switch (event.getKind()) { 612 case DebugEvent.SUSPEND: 613 if (source instanceof IThread) { 614 IThread thread = (IThread)source; 615 try { 616 IStackFrame frame = thread.getTopStackFrame(); 617 queueData(frame); 618 } catch (DebugException e) { 619 } 620 } 621 break; 622 case DebugEvent.RESUME: 623 if (source instanceof IThread && event.getDetail() == DebugEvent.CLIENT_REQUEST) { 624 try { 627 IDebugTarget target = ((IThread) source).getDebugTarget(); 628 IThread[] threads= target.getThreads(); 629 for (int j = 0; j < threads.length; j++) { 630 IStackFrame frame = threads[j].getTopStackFrame(); 631 if (frame != null) { 632 queueData(frame); 633 break; 634 } 635 } 636 } catch (DebugException e) { 637 } 638 } 639 break; 640 } 641 } 642 return events; 643 } 644 } 645 | Popular Tags |