1 11 package org.eclipse.core.internal.jobs; 12 13 import java.util.HashMap ; 14 import java.util.Stack ; 15 import org.eclipse.core.internal.runtime.RuntimeLog; 16 import org.eclipse.core.runtime.*; 17 import org.eclipse.core.runtime.jobs.ISchedulingRule; 18 import org.eclipse.core.runtime.jobs.LockListener; 19 20 28 public class LockManager { 29 33 private static class LockState { 34 private int depth; 35 private OrderedLock lock; 36 37 40 protected static LockState suspend(OrderedLock lock) { 41 LockState state = new LockState(); 42 state.lock = lock; 43 state.depth = lock.forceRelease(); 44 return state; 45 } 46 47 50 public void resume() { 51 while (true) { 55 try { 56 if (lock.acquire(Long.MAX_VALUE)) 57 break; 58 } catch (InterruptedException e) { 59 } 61 } 62 lock.setDepth(depth); 63 } 64 } 65 66 protected LockListener lockListener; 68 72 private DeadlockDetector locks = new DeadlockDetector(); 73 79 private HashMap suspendedLocks = new HashMap (); 80 81 public LockManager() { 82 super(); 83 } 84 85 88 public void aboutToRelease() { 89 if (lockListener == null) 90 return; 91 try { 92 lockListener.aboutToRelease(); 93 } catch (Exception e) { 94 handleException(e); 95 } catch (LinkageError e) { 96 handleException(e); 97 } 98 } 99 100 103 public boolean aboutToWait(Thread lockOwner) { 104 if (lockListener == null) 105 return false; 106 try { 107 return lockListener.aboutToWait(lockOwner); 108 } catch (Exception e) { 109 handleException(e); 110 } catch (LinkageError e) { 111 handleException(e); 112 } 113 return false; 114 } 115 116 119 void addLockThread(Thread thread, ISchedulingRule lock) { 120 if (locks == null) 121 return; 122 try { 123 synchronized (locks) { 124 locks.lockAcquired(thread, lock); 125 } 126 } catch (Exception e) { 127 handleInternalError(e); 128 } 129 } 130 131 134 void addLockWaitThread(Thread thread, ISchedulingRule lock) { 135 if (locks == null) 136 return; 137 try { 138 Deadlock found = null; 139 synchronized (locks) { 140 found = locks.lockWaitStart(thread, lock); 141 } 142 if (found == null) 143 return; 144 ISchedulingRule[] toSuspend = found.getLocks(); 147 LockState[] suspended = new LockState[toSuspend.length]; 148 for (int i = 0; i < toSuspend.length; i++) 149 suspended[i] = LockState.suspend((OrderedLock) toSuspend[i]); 150 synchronized (suspendedLocks) { 151 Stack prevLocks = (Stack ) suspendedLocks.get(found.getCandidate()); 152 if (prevLocks == null) 153 prevLocks = new Stack (); 154 prevLocks.push(suspended); 155 suspendedLocks.put(found.getCandidate(), prevLocks); 156 } 157 } catch (Exception e) { 158 handleInternalError(e); 159 } 160 } 161 162 166 private static void handleException(Throwable e) { 167 IStatus status; 168 if (e instanceof CoreException) { 169 status = new MultiStatus(JobManager.PI_JOBS, JobManager.PLUGIN_ERROR, "LockManager.handleException", e); ((MultiStatus) status).merge(((CoreException) e).getStatus()); 172 } else { 173 status = new Status(IStatus.ERROR, JobManager.PI_JOBS, JobManager.PLUGIN_ERROR, "LockManager.handleException", e); } 175 RuntimeLog.log(status); 176 } 177 178 183 private void handleInternalError(Throwable t) { 184 try { 185 handleException(t); 186 handleException(new Exception (locks.toDebugString())); 187 } catch (Exception e2) { 188 } 190 locks = null; 192 } 193 194 198 public boolean isEmpty() { 199 return locks.isEmpty(); 200 } 201 202 205 public boolean isLockOwner() { 206 Thread current = Thread.currentThread(); 209 if (current instanceof Worker) 210 return true; 211 if (locks == null) 212 return false; 213 synchronized (locks) { 214 return locks.contains(Thread.currentThread()); 215 } 216 } 217 218 221 public synchronized OrderedLock newLock() { 222 return new OrderedLock(this); 223 } 224 225 228 void removeLockCompletely(Thread thread, ISchedulingRule rule) { 229 if (locks == null) 230 return; 231 try { 232 synchronized (locks) { 233 locks.lockReleasedCompletely(thread, rule); 234 } 235 } catch (Exception e) { 236 handleInternalError(e); 237 } 238 } 239 240 243 void removeLockThread(Thread thread, ISchedulingRule lock) { 244 try { 245 synchronized (locks) { 246 locks.lockReleased(thread, lock); 247 } 248 } catch (Exception e) { 249 handleInternalError(e); 250 } 251 } 252 253 256 void removeLockWaitThread(Thread thread, ISchedulingRule lock) { 257 try { 258 synchronized (locks) { 259 locks.lockWaitStop(thread, lock); 260 } 261 } catch (Exception e) { 262 handleInternalError(e); 263 } 264 } 265 266 269 void resumeSuspendedLocks(Thread owner) { 270 LockState[] toResume; 271 synchronized (suspendedLocks) { 272 Stack prevLocks = (Stack ) suspendedLocks.get(owner); 273 if (prevLocks == null) 274 return; 275 toResume = (LockState[]) prevLocks.pop(); 276 if (prevLocks.empty()) 277 suspendedLocks.remove(owner); 278 } 279 for (int i = 0; i < toResume.length; i++) 280 toResume[i].resume(); 281 } 282 283 public void setLockListener(LockListener listener) { 284 this.lockListener = listener; 285 } 286 } 287 | Popular Tags |