diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java')
-rw-r--r-- | plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java | 103 |
1 files changed, 69 insertions, 34 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java index c06096095b..1e2ad3e23b 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java @@ -23,6 +23,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionKey; import org.eclipse.emf.cdo.server.IView; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.spi.server.InternalLockManager; +import org.eclipse.emf.cdo.spi.server.InternalSession; import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; @@ -38,12 +39,16 @@ import java.util.List; */ public class LockObjectsIndication extends CDOReadIndication { - private List<Object> objectsToBeLocked = new ArrayList<Object>(); - private List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>(); private boolean timedOut; + private boolean passiveUpdatesEnabled; + + private long requiredTimestamp; + + private boolean staleNoUpdate; + public LockObjectsIndication(CDOServerProtocol protocol) { super(protocol, CDOProtocolConstants.SIGNAL_LOCK_OBJECTS); @@ -52,6 +57,9 @@ public class LockObjectsIndication extends CDOReadIndication @Override protected void indicating(CDODataInput in) throws IOException { + InternalSession session = getSession(); + passiveUpdatesEnabled = session.isPassiveUpdateEnabled(); + int viewID = in.readInt(); LockType lockType = in.readCDOLockType(); long timeout = in.readLong(); @@ -62,16 +70,24 @@ public class LockObjectsIndication extends CDOReadIndication for (int i = 0; i < nRevisions; i++) { revKeys[i] = in.readCDORevisionKey(); - handleViewedRevision(viewedBranch, revKeys[i]); } - if (staleRevisions.size() > 0) + List<Object> objectsToBeLocked = new ArrayList<Object>(); + boolean isSupportingBranches = getRepository().isSupportingBranches(); + for (CDORevisionKey revKey : revKeys) { - // If we have 1 or more stale revisions, we should not lock - return; + CDOID id = revKey.getID(); + if (isSupportingBranches) + { + objectsToBeLocked.add(CDOIDUtil.createIDAndBranch(id, viewedBranch)); + } + else + { + objectsToBeLocked.add(id); + } } - IView view = getSession().getView(viewID); + IView view = session.getView(viewID); InternalLockManager lockManager = getRepository().getLockManager(); try { @@ -80,51 +96,51 @@ public class LockObjectsIndication extends CDOReadIndication catch (TimeoutRuntimeException ex) { timedOut = true; + return; } catch (InterruptedException ex) { throw WrappedException.wrap(ex); } - } - private void handleViewedRevision(CDOBranch viewedBranch, CDORevisionKey revKey) - { - CDOID id = revKey.getID(); - InternalCDORevision rev = getRepository().getRevisionManager().getRevision(id, viewedBranch.getHead(), - CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, true); - - if (rev == null) + try { - throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id, - viewedBranch)); + for (CDORevisionKey revKey : revKeys) + { + checkStale(viewedBranch, revKey); + } } - - if (!revKey.equals(rev)) + catch (IllegalArgumentException ex) { - staleRevisions.add(revKey); - - // If we have 1 or more stale revisions, the locking won't proceed for sure, - // so we can return early - return; + lockManager.unlock(lockType, view, objectsToBeLocked); + throw ex; } - if (getRepository().isSupportingBranches()) - { - objectsToBeLocked.add(CDOIDUtil.createIDAndBranch(id, viewedBranch)); - } - else + // If some of the clients' revisions are stale and it has passiveUpdates disabled, + // then the locks are useless so we release them and report the stale revisions (later) + staleNoUpdate = staleRevisions.size() > 0 && !passiveUpdatesEnabled; + if (staleNoUpdate) { - objectsToBeLocked.add(id); + lockManager.unlock(lockType, view, objectsToBeLocked); } } @Override protected void responding(CDODataOutput out) throws IOException { - boolean success = !timedOut && staleRevisions.size() == 0; - out.writeBoolean(success); - - if (!success) + boolean lockSuccesful = !timedOut && !staleNoUpdate; + out.writeBoolean(lockSuccesful); + + if (lockSuccesful) + { + boolean clientMustWait = staleRevisions.size() > 0; + out.writeBoolean(clientMustWait); + if (clientMustWait) + { + out.writeLong(requiredTimestamp); + } + } + else { out.writeBoolean(timedOut); if (!timedOut) @@ -137,4 +153,23 @@ public class LockObjectsIndication extends CDOReadIndication } } } + + private void checkStale(CDOBranch viewedBranch, CDORevisionKey revKey) + { + CDOID id = revKey.getID(); + InternalCDORevision rev = getRepository().getRevisionManager().getRevision(id, viewedBranch.getHead(), + CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, true); + + if (rev == null) + { + throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id, + viewedBranch)); + } + + if (!revKey.equals(rev)) + { + staleRevisions.add(revKey); + requiredTimestamp = Math.max(requiredTimestamp, rev.getTimeStamp()); + } + } } |