1 11 package org.eclipse.core.internal.jobs; 12 13 import org.eclipse.core.runtime.Assert; 14 import org.eclipse.core.runtime.jobs.ILock; 15 import org.eclipse.core.runtime.jobs.ISchedulingRule; 16 17 35 public class OrderedLock implements ILock, ISchedulingRule { 36 37 private static final boolean DEBUG = false; 38 41 private static int nextLockNumber = 0; 42 45 private volatile Thread currentOperationThread; 46 51 private int depth; 52 55 private final LockManager manager; 56 private final int number; 57 58 63 private final Queue operations = new Queue(); 64 65 68 OrderedLock(LockManager manager) { 69 this.manager = manager; 70 this.number = nextLockNumber++; 71 } 72 73 76 public void acquire() { 77 while (true) { 81 try { 82 if (acquire(Long.MAX_VALUE)) 83 return; 84 } catch (InterruptedException e) { 85 } 87 } 88 } 89 90 93 public boolean acquire(long delay) throws InterruptedException { 94 if (Thread.interrupted()) 95 throw new InterruptedException (); 96 97 boolean success = false; 98 if (delay <= 0) 99 return attempt(); 100 Semaphore semaphore = createSemaphore(); 101 if (semaphore == null) 102 return true; 103 if (DEBUG) 104 System.out.println("[" + Thread.currentThread() + "] Operation waiting to be executed... " + this); success = doAcquire(semaphore, delay); 106 manager.resumeSuspendedLocks(Thread.currentThread()); 107 if (DEBUG && success) 108 System.out.println("[" + Thread.currentThread() + "] Operation started... " + this); else if (DEBUG) 110 System.out.println("[" + Thread.currentThread() + "] Operation timed out... " + this); return success; 112 } 113 114 118 private synchronized boolean attempt() { 119 if ((currentOperationThread == Thread.currentThread()) || (currentOperationThread == null && operations.isEmpty())) { 122 depth++; 123 setCurrentOperationThread(Thread.currentThread()); 124 return true; 125 } 126 return false; 127 } 128 129 132 public boolean contains(ISchedulingRule rule) { 133 return false; 134 } 135 136 141 private synchronized Semaphore createSemaphore() { 142 return attempt() ? null : enqueue(new Semaphore(Thread.currentThread())); 143 } 144 145 149 private boolean doAcquire(Semaphore semaphore, long delay) throws InterruptedException { 150 boolean success = false; 151 if (manager.aboutToWait(this.currentOperationThread)) { 153 removeFromQueue(semaphore); 157 depth++; 158 manager.addLockThread(currentOperationThread, this); 159 return true; 160 } 161 semaphore = createSemaphore(); 165 if (semaphore == null) 166 return true; 167 manager.addLockWaitThread(Thread.currentThread(), this); 168 try { 169 success = semaphore.acquire(delay); 170 } catch (InterruptedException e) { 171 if (DEBUG) 172 System.out.println("[" + Thread.currentThread() + "] Operation interrupted while waiting... :-|"); throw e; 174 } 175 if (success) { 176 depth++; 177 updateCurrentOperation(); 178 } else { 179 removeFromQueue(semaphore); 180 manager.removeLockWaitThread(Thread.currentThread(), this); 181 } 182 return success; 183 } 184 185 189 private synchronized void doRelease() { 190 manager.aboutToRelease(); 192 depth = 0; 193 Semaphore next = (Semaphore) operations.peek(); 194 setCurrentOperationThread(null); 195 if (next != null) 196 next.release(); 197 } 198 199 203 private synchronized Semaphore enqueue(Semaphore newSemaphore) { 204 Semaphore semaphore = (Semaphore) operations.get(newSemaphore); 205 if (semaphore == null) { 206 operations.enqueue(newSemaphore); 207 return newSemaphore; 208 } 209 return semaphore; 210 } 211 212 216 protected int forceRelease() { 217 int oldDepth = depth; 218 doRelease(); 219 return oldDepth; 220 } 221 222 225 public int getDepth() { 226 return depth; 227 } 228 229 232 public boolean isConflicting(ISchedulingRule rule) { 233 return rule == this; 234 } 235 236 239 public void release() { 240 if (depth == 0) 241 return; 242 Assert.isTrue(depth >= 0, "Lock released too many times"); if (--depth == 0) 245 doRelease(); 246 else 247 manager.removeLockThread(currentOperationThread, this); 248 } 249 250 255 private synchronized void removeFromQueue(Semaphore semaphore) { 256 operations.remove(semaphore); 257 } 258 259 263 private void setCurrentOperationThread(Thread newThread) { 264 if ((currentOperationThread != null) && (newThread == null)) 265 manager.removeLockThread(currentOperationThread, this); 266 this.currentOperationThread = newThread; 267 if (currentOperationThread != null) 268 manager.addLockThread(currentOperationThread, this); 269 } 270 271 275 protected void setDepth(int newDepth) { 276 for (int i = depth; i < newDepth; i++) { 277 manager.addLockThread(currentOperationThread, this); 278 } 279 this.depth = newDepth; 280 } 281 282 285 public String toString() { 286 return "OrderedLock (" + number + ")"; } 288 289 293 private synchronized void updateCurrentOperation() { 294 operations.dequeue(); 295 setCurrentOperationThread(Thread.currentThread()); 296 } 297 } 298 | Popular Tags |