diff options
Diffstat (limited to 'plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java')
-rw-r--r-- | plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java | 171 |
1 files changed, 93 insertions, 78 deletions
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java index 437445d636..565ba7925d 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java @@ -40,6 +40,8 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_CONCURRENCY, RWOLockManager.class); + private static final ThreadLocal<Boolean> UNLOCK_ALL = new ThreadLocal<Boolean>(); + private final List<LockState<OBJECT, CONTEXT>> EMPTY_RESULT = Collections.emptyList(); private final Map<OBJECT, LockState<OBJECT, CONTEXT>> objectToLockStateMap = createObjectToLocksMap(); @@ -106,7 +108,7 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo lock(type, context, Collections.singleton(objectToLock), timeout); } - public synchronized void unlock(LockType type, CONTEXT context, Collection<? extends OBJECT> objectsToUnlock) + public void unlock(LockType type, CONTEXT context, Collection<? extends OBJECT> objectsToUnlock) { unlock2(type, context, objectsToUnlock); } @@ -114,57 +116,18 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo public synchronized List<LockState<OBJECT, CONTEXT>> unlock2(CONTEXT context, Collection<? extends OBJECT> objectsToUnlock) { - if (objectsToUnlock.isEmpty()) - { - return EMPTY_RESULT; - } - - if (TRACER.isEnabled()) - { - TRACER.format("Unlock : {0} --> {1}", objectsToUnlock, context); //$NON-NLS-1$ - } - - Set<LockState<OBJECT, CONTEXT>> lockStates = new HashSet<LockState<OBJECT, CONTEXT>>(); - - Iterator<? extends OBJECT> it = objectsToUnlock.iterator(); - while (it.hasNext()) - { - OBJECT o = it.next(); - LockState<OBJECT, CONTEXT> lockState = objectToLockStateMap.get(o); - - if (lockState == null) - { - continue; - } - - for (LockType lockType : LockType.values()) - { - while (lockState.canUnlock(lockType, context)) - { - lockState.unlock(lockType, context); - lockStates.add(lockState); - } - } - } - - for (LockState<OBJECT, CONTEXT> lockState : lockStates) - { - removeLockStateForContext(context, lockState); - - if (lockState.hasNoLocks()) - { - objectToLockStateMap.remove(lockState.getLockedObject()); - } - } - - notifyAll(); - - return new LinkedList<RWOLockManager.LockState<OBJECT, CONTEXT>>(lockStates); + return unlock2(LockType.values(), context, objectsToUnlock); } public synchronized List<LockState<OBJECT, CONTEXT>> unlock2(LockType type, CONTEXT context, Collection<? extends OBJECT> objectsToUnlock) { + return unlock2(new LockType[] { type }, context, objectsToUnlock); + } + + private List<LockState<OBJECT, CONTEXT>> unlock2(LockType[] types, CONTEXT context, + Collection<? extends OBJECT> objectsToUnlock) + { if (objectsToUnlock.isEmpty()) { return EMPTY_RESULT; @@ -172,25 +135,34 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo if (TRACER.isEnabled()) { - TRACER.format("Unlock", objectsToUnlock, context); //$NON-NLS-1$ + TRACER.format("Unlock: {0} --> {1}", context, objectsToUnlock); //$NON-NLS-1$ } - List<LockState<OBJECT, CONTEXT>> lockStates = new LinkedList<LockState<OBJECT, CONTEXT>>(); + Set<LockState<OBJECT, CONTEXT>> result = new HashSet<LockState<OBJECT, CONTEXT>>(); - Iterator<? extends OBJECT> it = objectsToUnlock.iterator(); - while (it.hasNext()) + for (OBJECT o : objectsToUnlock) { - OBJECT o = it.next(); LockState<OBJECT, CONTEXT> lockState = objectToLockStateMap.get(o); - if (lockState != null && lockState.canUnlock(type, context)) + if (lockState != null) { - lockStates.add(lockState); + for (LockType type : types) + { + while (lockState.canUnlock(type, context)) + { + lockState.unlock(type, context); + result.add(lockState); + + if (UNLOCK_ALL.get() != Boolean.TRUE) + { + break; + } + } + } } } - for (LockState<OBJECT, CONTEXT> lockState : lockStates) + for (LockState<OBJECT, CONTEXT> lockState : result) { - lockState.unlock(type, context); if (!lockState.hasLocks(context)) { removeLockStateForContext(context, lockState); @@ -204,7 +176,7 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo notifyAll(); - return lockStates; + return new LinkedList<RWOLockManager.LockState<OBJECT, CONTEXT>>(result); } public synchronized void unlock(CONTEXT context) @@ -229,11 +201,11 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo for (LockState<OBJECT, CONTEXT> lockState : lockStates) { - for (LockType lockType : LockType.values()) + for (LockType type : LockType.values()) { - while (lockState.hasLock(lockType, context, false)) + while (lockState.hasLock(type, context, false)) { - lockState.unlock(lockType, context); + lockState.unlock(type, context); } } @@ -442,6 +414,22 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo wait(waitTime); } + + } + + /** + * @since 3.7 + */ + public static void setUnlockAll(boolean on) + { + if (on) + { + UNLOCK_ALL.set(Boolean.TRUE); + } + else + { + UNLOCK_ALL.remove(); + } } /** @@ -482,8 +470,7 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo return lockedObject; } - public boolean hasLock(org.eclipse.net4j.util.concurrent.IRWLockManager.LockType type, CONTEXT view, - boolean byOthers) + public boolean hasLock(LockType type, CONTEXT view, boolean byOthers) { CheckUtil.checkArg(view, "view"); @@ -517,7 +504,7 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo return false; } - public boolean hasLock(org.eclipse.net4j.util.concurrent.IRWLockManager.LockType type) + public boolean hasLock(LockType type) { switch (type) { @@ -534,6 +521,49 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo return false; } + public Set<CONTEXT> getReadLockOwners() + { + return Collections.unmodifiableSet(readLockOwners); + } + + public CONTEXT getWriteLockOwner() + { + return writeLockOwner; + } + + public CONTEXT getWriteOptionOwner() + { + return writeOptionOwner; + } + + @Override + public int hashCode() + { + return lockedObject.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + + if (obj == null) + { + return false; + } + + if (!(obj instanceof LockState)) + { + return false; + } + + LockState<?, ?> other = (LockState<?, ?>)obj; + return lockedObject.equals(other.lockedObject); + } + @Override public String toString() { @@ -808,20 +838,5 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo { writeOptionOwner = null; } - - public Set<CONTEXT> getReadLockOwners() - { - return Collections.unmodifiableSet(readLockOwners); - } - - public CONTEXT getWriteLockOwner() - { - return writeLockOwner; - } - - public CONTEXT getWriteOptionOwner() - { - return writeOptionOwner; - } } } |