1 11 package org.eclipse.jdt.internal.debug.ui.monitors; 12 13 14 import java.util.ArrayList ; 15 import java.util.HashSet ; 16 import java.util.Hashtable ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 21 import org.eclipse.debug.core.DebugException; 22 import org.eclipse.debug.core.model.IThread; 23 import org.eclipse.jdt.debug.core.IJavaDebugTarget; 24 import org.eclipse.jdt.debug.core.IJavaObject; 25 import org.eclipse.jdt.debug.core.IJavaThread; 26 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; 27 28 31 32 public class MonitorManager { 33 34 37 private Map fThreadToOwnedMonitors; 38 39 42 private Map fThreadToContendedMonitor; 43 44 47 private Map fMonitorToOwningThread; 48 49 52 private Map fMonitorToContendingThreads; 53 54 private static MonitorManager fgDefault= null; 55 56 private DeadLocksViewContentProvider fDeadlockUpdateListener; 57 58 61 private List fDeadLockLists; 62 63 66 private MonitorManager() { 67 fThreadToOwnedMonitors= new Hashtable (4); 69 fThreadToContendedMonitor= new Hashtable (4); 70 fMonitorToOwningThread= new Hashtable (); 71 fMonitorToContendingThreads= new Hashtable (); 72 fDeadLockLists = new ArrayList (); 73 } 74 75 public static MonitorManager getDefault() { 76 if (fgDefault == null) { 77 fgDefault= new MonitorManager(); 78 } 79 return fgDefault; 80 } 81 82 88 protected void addThreadWithOwnedMonitors(IJavaThread thread, IJavaObject[] monitors) { 89 if (monitors == null) { 90 fThreadToOwnedMonitors.remove(thread); 91 } else { 92 fThreadToOwnedMonitors.put(thread, monitors); 93 } 94 } 95 96 102 protected void addThreadWithContendedMonitor(IJavaThread thread, IJavaObject monitor) { 103 if (monitor == null) { 104 fThreadToContendedMonitor.remove(thread); 105 } else { 106 fThreadToContendedMonitor.put(thread, monitor); 107 } 108 } 109 110 116 protected void addMonitorWithOwningThread(IJavaObject monitor, IJavaThread thread) { 117 if (monitor == null) { 118 fMonitorToOwningThread.remove(monitor); 119 } else { 120 fMonitorToOwningThread.put(monitor, thread); 121 } 122 } 123 124 130 protected void addMonitorWithContendedThread(IJavaObject monitor, IJavaThread thread) { 131 if (monitor == null) { 132 fMonitorToContendingThreads.remove(monitor); 133 } else { 134 List threads= (List )fMonitorToContendingThreads.get(monitor); 135 if (threads == null) { 136 threads= new ArrayList (); 137 fMonitorToContendingThreads.put(monitor, threads); 138 } 139 threads.add(thread); 140 } 141 } 142 143 150 public IJavaObject[] getOwnedMonitors(IJavaThread thread) { 151 return (IJavaObject[])fThreadToOwnedMonitors.get(thread); 152 } 153 154 160 public IJavaObject getContendedMonitor(IJavaThread thread) { 161 return (IJavaObject)fThreadToContendedMonitor.get(thread); 162 } 163 164 171 public IJavaThread getOwningThread(IJavaObject monitor) { 172 return (IJavaThread)fMonitorToOwningThread.get(monitor); 173 } 174 175 181 public List getContendingThreads(IJavaObject monitor) { 182 Object obj = fMonitorToContendingThreads.get(monitor); 183 return (List )obj; 184 } 185 186 191 public IJavaThread[] getThreads() { 192 Set all= new HashSet (); 193 all.addAll(fThreadToContendedMonitor.keySet()); 194 all.addAll(fThreadToOwnedMonitors.keySet()); 195 return (IJavaThread[])all.toArray(new IJavaThread[all.size()]); 196 } 197 198 203 public IJavaObject[] getMonitors() { 204 Set all= new HashSet (); 205 all.addAll(fMonitorToContendingThreads.keySet()); 206 all.addAll(fMonitorToOwningThread.keySet()); 207 return (IJavaObject[])all.toArray(new IJavaObject[all.size()]); 208 } 209 210 216 public void update(IJavaDebugTarget target){ 217 218 removeMonitorInformation(target); 219 220 if (!target.supportsMonitorInformation()) { 221 return; 222 } 223 if (fDeadlockUpdateListener != null) { 224 fDeadlockUpdateListener.clearDeadlockInformation(); 225 } 226 update(target, true); 227 } 228 229 237 public void updatePartial(IJavaDebugTarget target){ 238 239 removeMonitorInformation(target); 240 241 if (!target.supportsMonitorInformation()) { 242 return; 243 } 244 245 if (fDeadlockUpdateListener != null) { 246 fDeadlockUpdateListener.clearDeadlockInformation(); 247 } 248 249 update(target, false); 250 } 251 252 261 private void update(IJavaDebugTarget target, boolean suspendThreads){ 262 263 try { 264 IThread[] threadResult= target.getThreads(); 266 List threadsList = new ArrayList (threadResult.length); 267 IJavaThread thread; 268 for (int i = 0; i < threadResult.length; i++) { 269 thread = (IJavaThread)threadResult[i]; 270 threadsList.add(thread); 271 } 272 IJavaThread[] threads= (IJavaThread[]) threadsList.toArray(new IJavaThread[threadsList.size()]); 273 274 if (suspendThreads) { 275 suspend(threads); 277 } 278 279 for (int i = 0; i < threads.length; i++) { 282 thread = threads[i]; 283 updateMonitors(thread); 284 } 285 for (int i = 0; i < threads.length; i++) { 288 thread = threads[i]; 289 updateDeadlock(thread); 290 } 291 } catch(DebugException e){ 292 } 293 } 294 295 private void updateDeadlock(IJavaThread thread) { 296 List l = listToDeadlock(thread, new ArrayList (4)); 298 if(l != null){ 301 ThreadWrapper tw = new ThreadWrapper(thread, l); 302 fDeadLockLists.add(tw); 304 } 305 } 306 307 private void updateMonitors(IJavaThread thread) throws DebugException { 308 IJavaObject[] ownedMonitors; 309 IJavaObject currentContendedMonitor; 310 IJavaObject monitor; 311 ownedMonitors = thread.getOwnedMonitors(); 312 currentContendedMonitor = thread.getContendedMonitor(); 313 if(thread.hasOwnedMonitors()){ 315 addThreadWithOwnedMonitors(thread, ownedMonitors); 316 317 for(int j=0; j < ownedMonitors.length; j++) { 318 monitor = ownedMonitors[j]; 319 addMonitorWithOwningThread(monitor, thread); 320 } 321 } 322 if(currentContendedMonitor != null){ 324 addThreadWithContendedMonitor(thread, currentContendedMonitor); 325 addMonitorWithContendedThread(currentContendedMonitor, thread); 326 } 327 } 328 329 333 private void suspend(IJavaThread[] threads){ 334 try { 335 for (int i = 0; i < threads.length; i++) { 336 IJavaThread thread = threads[i]; 337 if (!thread.isSuspended()) { 338 thread.suspend(); 339 while (!thread.isSuspended()) { 340 Thread.sleep(100); 341 } 342 } 343 } 344 } 345 catch (DebugException e) { 346 JDIDebugUIPlugin.log(e); 347 } 348 catch (InterruptedException e){ 349 JDIDebugUIPlugin.log(e); 350 } 351 } 352 353 358 public void removeMonitorInformation(IJavaDebugTarget target) { 359 fThreadToOwnedMonitors.clear(); 360 fThreadToContendedMonitor.clear(); 361 fMonitorToOwningThread.clear(); 362 fMonitorToContendingThreads.clear(); 363 fDeadLockLists.clear(); 364 if (fDeadlockUpdateListener != null) { 365 fDeadlockUpdateListener.clearDeadlockInformation(); 366 } 367 } 368 369 385 private List listToDeadlock(IJavaThread thread, List usedThreadsList){ 386 387 List res = new ArrayList (); 388 IJavaObject contendedMonitor = (IJavaObject)fThreadToContendedMonitor.get(thread); 389 390 if(contendedMonitor!=null){ 392 393 IJavaThread owningThread = (IJavaThread)fMonitorToOwningThread.get(contendedMonitor); 394 if(usedThreadsList.contains(owningThread)){ 397 res.add(thread); 398 res.add(contendedMonitor); 399 res.add(owningThread); 400 return res; 401 } 402 else{ 404 List newUsedThreadsList= new ArrayList (usedThreadsList); 405 406 newUsedThreadsList.add(thread); 408 409 if(owningThread==null){ 410 return null; 411 } 412 List newRes = listToDeadlock(owningThread, newUsedThreadsList); 414 415 if(newRes!=null){ 416 res.add(thread); 417 res.add(contendedMonitor); 418 res.addAll(newRes); 419 return res; 420 } 421 } 422 } else { 423 return null; 425 } 426 return null; 427 } 428 429 434 public int getNumberOfDeadlocks() { 435 return fDeadLockLists.size(); 436 } 437 438 445 public List getDeadlockList(int index) { 446 if (index >= fDeadLockLists.size()) { 447 return null; 448 } 449 return ((ThreadWrapper)fDeadLockLists.get(index)).getDeadLockList(); 450 } 451 452 460 public IJavaThread getStartThread(int index) { 461 if (index >= fDeadLockLists.size()) { 462 return null; 463 } 464 return ((ThreadWrapper)fDeadLockLists.get(index)).getStartThread(); 465 } 466 467 473 public boolean isCaughtInDeadlock(IJavaThread thread){ 474 for (int i = 0; i < fDeadLockLists.size(); i++) { 475 if(((ThreadWrapper)fDeadLockLists.get(i)).getStartThread().equals(thread)){ 476 return true; 477 } 478 } 479 return false; 480 } 481 482 protected void addDeadlockUpdateListener(DeadLocksViewContentProvider provider) { 483 fDeadlockUpdateListener= provider; 484 } 485 486 protected void removeDeadlockUpdateListener() { 487 fDeadlockUpdateListener= null; 488 } 489 } 490 | Popular Tags |