1 11 package org.eclipse.debug.internal.ui.viewers.update; 12 13 import java.util.HashMap ; 14 import java.util.LinkedHashSet ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 import org.eclipse.debug.core.DebugEvent; 19 import org.eclipse.debug.core.DebugException; 20 import org.eclipse.debug.core.DebugPlugin; 21 import org.eclipse.debug.core.ILaunch; 22 import org.eclipse.debug.core.ILaunchManager; 23 import org.eclipse.debug.core.model.IDebugTarget; 24 import org.eclipse.debug.core.model.IStackFrame; 25 import org.eclipse.debug.core.model.IThread; 26 import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; 27 import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; 28 import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; 29 30 33 public class ThreadEventHandler extends DebugEventHandler { 34 35 40 private Set fThreadQueue = new LinkedHashSet (); 41 42 45 private Map fLastTopFrame = new HashMap (); 46 51 public ThreadEventHandler(AbstractModelProxy proxy) { 52 super(proxy); 53 } 54 55 58 public synchronized void dispose() { 59 fLastTopFrame.clear(); 60 fThreadQueue.clear(); 61 super.dispose(); 62 } 63 64 protected void handleSuspend(DebugEvent event) { 65 IThread thread = (IThread) event.getSource(); 66 if (event.isEvaluation()) { 67 ModelDelta delta = buildRootDelta(); 68 ModelDelta node = addPathToThread(delta, thread); 69 node = node.addNode(thread, IModelDelta.NO_CHANGE); 70 try { 71 IStackFrame frame = thread.getTopStackFrame(); 72 if (frame != null) { 73 int flag = IModelDelta.NO_CHANGE; 74 if (event.getDetail() == DebugEvent.EVALUATION) { 75 flag = flag | IModelDelta.CONTENT; 77 } else if (event.getDetail() == DebugEvent.EVALUATION_IMPLICIT) { 78 flag = flag | IModelDelta.STATE; 80 } 81 node.addNode(frame, flag); 82 fireDelta(delta); 83 } 84 } catch (DebugException e) { 85 } 86 } else { 87 queueSuspendedThread(event); 88 int extras = IModelDelta.STATE; 89 if (event.getDetail() == DebugEvent.BREAKPOINT | event.getDetail() == DebugEvent.CLIENT_REQUEST) { 90 extras = IModelDelta.EXPAND; 91 } 92 fireDeltaUpdatingTopFrame(thread, IModelDelta.NO_CHANGE | extras, event); 93 } 94 } 95 96 private boolean isEqual(Object o1, Object o2) { 97 if (o1 == o2) { 98 return true; 99 } 100 if (o1 == null) { 101 return false; 102 } 103 return o1.equals(o2); 104 } 105 106 protected void handleResume(DebugEvent event) { 107 IThread thread = removeSuspendedThread(event); 108 fireDeltaAndClearTopFrame(thread, IModelDelta.STATE | IModelDelta.CONTENT | IModelDelta.SELECT); 109 thread = getNextSuspendedThread(); 110 if (thread != null) { 111 fireDeltaUpdatingTopFrame(thread, IModelDelta.NO_CHANGE, event); 112 } 113 } 114 115 protected void handleCreate(DebugEvent event) { 116 fireDeltaAndClearTopFrame((IThread) event.getSource(), IModelDelta.ADDED | IModelDelta.STATE); 117 } 118 119 protected void handleTerminate(DebugEvent event) { 120 IThread thread = (IThread) event.getSource(); 121 IDebugTarget target = thread.getDebugTarget(); 122 if (!(target.isTerminated() || target.isDisconnected())) { 124 fireDeltaAndClearTopFrame(thread, IModelDelta.REMOVED); 125 } 126 } 127 128 protected void handleChange(DebugEvent event) { 129 if (event.getDetail() == DebugEvent.STATE) { 130 fireDeltaUpdatingThread((IThread) event.getSource(), IModelDelta.STATE); 131 } else { 132 fireDeltaUpdatingThread((IThread) event.getSource(), IModelDelta.CONTENT); 133 } 134 } 135 136 protected void handleLateSuspend(DebugEvent suspend, DebugEvent resume) { 137 IThread thread = queueSuspendedThread(suspend); 138 if (suspend.isEvaluation() && suspend.getDetail() == DebugEvent.EVALUATION_IMPLICIT) { 139 ModelDelta delta = buildRootDelta(); 141 ModelDelta node = addPathToThread(delta, thread); 142 node = node.addNode(thread, IModelDelta.STATE); 143 try { 144 IStackFrame frame = thread.getTopStackFrame(); 145 if (frame != null) { 146 node.addNode(frame, IModelDelta.STATE); 147 fireDelta(delta); 148 } 149 } catch (DebugException e) { 150 } 151 } else { 152 fireDeltaUpdatingTopFrame(thread, IModelDelta.CONTENT | IModelDelta.EXPAND, resume); 153 } 154 } 155 156 protected void handleSuspendTimeout(DebugEvent event) { 157 IThread thread = removeSuspendedThread(event); 158 fireDeltaUpdatingThread(thread, IModelDelta.STATE); 160 } 161 162 protected ModelDelta buildRootDelta() { 163 return new ModelDelta(getLaunchManager(), IModelDelta.NO_CHANGE); 164 } 165 166 171 protected ILaunchManager getLaunchManager() { 172 return DebugPlugin.getDefault().getLaunchManager(); 173 } 174 175 182 protected ModelDelta addPathToThread(ModelDelta delta, IThread thread) { 183 ILaunch launch = thread.getLaunch(); 184 Object [] children = launch.getChildren(); 185 delta = delta.addNode(launch, indexOf(getLaunchManager().getLaunches(), launch), IModelDelta.NO_CHANGE, children.length); 186 IDebugTarget debugTarget = thread.getDebugTarget(); 187 int numThreads = -1; 188 try { 189 numThreads = debugTarget.getThreads().length; 190 } catch (DebugException e) { 191 } 192 return delta.addNode(debugTarget, indexOf(children, debugTarget), IModelDelta.NO_CHANGE, numThreads); 193 } 194 195 private void fireDeltaAndClearTopFrame(IThread thread, int flags) { 196 ModelDelta delta = buildRootDelta(); 197 ModelDelta node = addPathToThread(delta, thread); 198 node.addNode(thread, flags); 199 synchronized (this) { 200 fLastTopFrame.remove(thread); 201 } 202 fireDelta(delta); 203 } 204 205 private void fireDeltaUpdatingTopFrame(IThread thread, int flags, DebugEvent event) { 206 ModelDelta delta = buildRootDelta(); 207 ModelDelta node = addPathToThread(delta, thread); 208 IStackFrame prev = null; 209 synchronized (this) { 210 prev = (IStackFrame) fLastTopFrame.get(thread); 211 } 212 IStackFrame frame = null; 213 try { 214 frame = thread.getTopStackFrame(); 215 } catch (DebugException e) { 216 } 217 int threadIndex = indexOf(thread); 218 int childCount = childCount(thread); 219 if (isEqual(frame, prev)) { 220 if (frame == null) { 221 if (thread.isSuspended()) { 222 node = node.addNode(thread, threadIndex, flags | IModelDelta.STATE | IModelDelta.SELECT, childCount); 224 } 225 } else { 226 node = node.addNode(thread, threadIndex, flags, childCount); 227 } 228 } else { 229 if (prev == null && event.getDetail() == DebugEvent.STEP_END) { 230 flags = flags | IModelDelta.EXPAND; 232 } 233 node = node.addNode(thread, threadIndex, flags | IModelDelta.CONTENT, childCount); 234 } 235 if (frame != null) { 236 node.addNode(frame, indexOf(frame), IModelDelta.STATE | IModelDelta.SELECT, childCount(frame)); 237 } 238 synchronized (this) { 239 if (!isDisposed()) { 240 fLastTopFrame.put(thread, frame); 241 } 242 } 243 fireDelta(delta); 244 } 245 246 252 protected int indexOf(IThread thread) { 253 try { 254 return indexOf(thread.getDebugTarget().getThreads(), thread); 255 } catch (DebugException e) { 256 } 257 return -1; 258 } 259 260 266 protected int indexOf(IStackFrame frame) { 267 return 0; 268 } 269 270 276 protected int childCount(IThread thread) { 277 try { 278 return thread.getStackFrames().length; 279 } catch (DebugException e) { 280 } 281 return -1; 282 } 283 284 290 protected int childCount(IStackFrame frame) { 291 return 0; 292 } 293 294 private void fireDeltaUpdatingThread(IThread thread, int flags) { 295 ModelDelta delta = buildRootDelta(); 296 ModelDelta node = addPathToThread(delta, thread); 297 node = node.addNode(thread, flags); 298 fireDelta(delta); 299 } 300 301 protected boolean handlesEvent(DebugEvent event) { 302 return event.getSource() instanceof IThread; 303 } 304 305 protected synchronized IThread queueSuspendedThread(DebugEvent event) { 306 IThread thread = (IThread) event.getSource(); 307 if (!isDisposed()) { 308 fThreadQueue.add(thread); 309 } 310 return thread; 311 } 312 313 protected synchronized IThread removeSuspendedThread(DebugEvent event) { 314 IThread thread = (IThread)event.getSource(); 315 fThreadQueue.remove(thread); 316 return thread; 317 } 318 319 protected synchronized IThread queueSuspendedThread(IThread thread) { 320 if (!isDisposed()) { 321 fThreadQueue.add(thread); 322 } 323 return thread; 324 } 325 326 protected synchronized void removeQueuedThread(IThread thread) { 327 fThreadQueue.remove(thread); 328 } 329 330 protected synchronized IThread getNextSuspendedThread() { 331 if (!fThreadQueue.isEmpty()) { 332 return (IThread) fThreadQueue.iterator().next(); 333 } 334 return null; 335 } 336 337 } 338 | Popular Tags |