From b7e84a0e190445f303dc8fa918cd5a7c6c0670f6 Mon Sep 17 00:00:00 2001 From: Caspar De Groot Date: Thu, 18 Aug 2011 02:24:31 +0000 Subject: [353691] Add lock notifications and lock caching https://bugs.eclipse.org/bugs/show_bug.cgi?id=353691 --- .../internal/net4j/protocol/CDOServerProtocol.java | 25 ++++ .../protocol/CommitTransactionIndication.java | 23 ++++ .../protocol/EnableLockNotificationIndication.java | 45 +++++++ .../net4j/protocol/LockDelegationIndication.java | 94 +++++++++++++ .../net4j/protocol/LockNotificationRequest.java | 37 ++++++ .../net4j/protocol/LockObjectsIndication.java | 145 +++++---------------- .../net4j/protocol/LockStateIndication.java | 90 +++++++++++++ .../net4j/protocol/OpenViewIndication.java | 13 +- .../net4j/protocol/UnlockDelegationIndication.java | 65 +++++++++ .../net4j/protocol/UnlockObjectsIndication.java | 44 ++++--- 10 files changed, 447 insertions(+), 134 deletions(-) create mode 100644 plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java create mode 100644 plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java create mode 100644 plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockNotificationRequest.java create mode 100644 plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockStateIndication.java create mode 100644 plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockDelegationIndication.java (limited to 'plugins/org.eclipse.emf.cdo.server.net4j') diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java index 3f96f29834..a0fc0cbb82 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java @@ -16,6 +16,7 @@ package org.eclipse.emf.cdo.server.internal.net4j.protocol; import org.eclipse.emf.cdo.common.CDOCommonRepository; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.server.IRepositoryProvider; import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; @@ -154,6 +155,18 @@ public class CDOServerProtocol extends SignalProtocol implement } } + public void sendLockNotification(CDOLockChangeInfo lockChangeInfo) throws Exception + { + if (LifecycleUtil.isActive(getChannel())) + { + new LockNotificationRequest(this, lockChangeInfo).sendAsync(); + } + else + { + handleInactiveSession(); + } + } + protected void handleInactiveSession() { OM.LOG.warn("Session channel is inactive: " + this); //$NON-NLS-1$ @@ -251,6 +264,12 @@ public class CDOServerProtocol extends SignalProtocol implement case CDOProtocolConstants.SIGNAL_UNLOCK_OBJECTS: return new UnlockObjectsIndication(this); + case CDOProtocolConstants.SIGNAL_LOCK_DELEGATION: + return new LockDelegationIndication(this); + + case CDOProtocolConstants.SIGNAL_UNLOCK_DELEGATION: + return new UnlockDelegationIndication(this); + case CDOProtocolConstants.SIGNAL_OBJECT_LOCKED: return new ObjectLockedIndication(this); @@ -287,6 +306,12 @@ public class CDOServerProtocol extends SignalProtocol implement case CDOProtocolConstants.SIGNAL_HANDLE_REVISIONS: return new HandleRevisionsIndication(this); + case CDOProtocolConstants.SIGNAL_LOCK_STATE: + return new LockStateIndication(this); + + case CDOProtocolConstants.SIGNAL_ENABLE_LOCK_NOTIFICATION: + return new EnableLockNotificationIndication(this); + default: return super.createSignalReactor(signalID); } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java index 7aa169ab3e..959e665695 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java @@ -15,10 +15,13 @@ package org.eclipse.emf.cdo.server.internal.net4j.protocol; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDReference; +import org.eclipse.emf.cdo.common.lock.CDOLockState; +import org.eclipse.emf.cdo.common.lock.CDOLockUtil; import org.eclipse.emf.cdo.common.model.EMFUtil; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.server.IView; import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; @@ -29,6 +32,7 @@ import org.eclipse.emf.cdo.spi.server.InternalTransaction; import org.eclipse.emf.cdo.spi.server.InternalView; import org.eclipse.net4j.util.WrappedException; +import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState; import org.eclipse.net4j.util.om.monitor.OMMonitor; import org.eclipse.net4j.util.om.monitor.ProgressDistributor; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -256,6 +260,7 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori { respondingResult(out); respondingMappingNewObjects(out); + respondingNewLockStates(out); } } finally @@ -312,6 +317,24 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori out.writeCDOID(CDOID.NULL); } + protected void respondingNewLockStates(CDODataOutput out) throws Exception + { + List> newLockStates = commitContext.getPostCommmitLockStates(); + if (newLockStates != null) + { + out.writeInt(newLockStates.size()); + for (LockState lockState : newLockStates) + { + CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState); + out.writeCDOLockState(cdoLockState); + } + } + else + { + out.writeInt(0); + } + } + protected InternalTransaction getTransaction(int viewID) { InternalView view = getSession().getView(viewID); diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java new file mode 100644 index 0000000000..34ca52a802 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.spi.server.InternalView; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class EnableLockNotificationIndication extends CDOServerIndication +{ + public EnableLockNotificationIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_ENABLE_LOCK_NOTIFICATION); + } + + @Override + protected void indicating(CDODataInput in) throws IOException + { + int viewID = in.readInt(); + boolean enable = in.readBoolean(); + + InternalView view = getSession().getView(viewID); + view.setLockNotificationEnabled(enable); + } + + @Override + protected void responding(CDODataOutput out) throws IOException + { + out.writeBoolean(true); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java new file mode 100644 index 0000000000..eaa67fd485 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea; +import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.server.IView; +import org.eclipse.emf.cdo.spi.server.InternalLockManager; +import org.eclipse.emf.cdo.spi.server.InternalSession; +import org.eclipse.emf.cdo.spi.server.InternalView; + +import org.eclipse.net4j.util.CheckUtil; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class LockDelegationIndication extends LockObjectsIndication +{ + private InternalView view; + + private String lockAreaID; + + public LockDelegationIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_LOCK_DELEGATION); + } + + @Override + protected void indicating(CDODataInput in) throws IOException + { + lockAreaID = in.readString(); + super.indicating(in); + } + + @Override + protected void responding(CDODataOutput out) throws IOException + { + try + { + super.responding(out); + } + finally + { + view.close(); + } + } + + @Override + protected IView getView(int viewID, CDOBranch viewedBranch) + { + // The view needs a lockArea... + InternalLockManager lockManager = getRepository().getLockManager(); + InternalSession session = getSession(); + LockArea lockArea; + + try + { + lockArea = lockManager.getLockArea(lockAreaID); + + // If we get here, the lockArea already exists. + view = (InternalView)lockManager.openView(session, InternalSession.TEMP_VIEW_ID, true, lockAreaID); + } + catch (LockAreaNotFoundException e) + { + // If we get here, the lockArea does not yet exist on the master, so we open + // a view without a lockArea first, then create a lockArea with the given ID, + // and associate it with the view. + view = session.openView(InternalSession.TEMP_VIEW_ID, viewedBranch.getHead()); + lockArea = lockManager.createLockArea(view, lockAreaID); + view.setDurableLockingID(lockAreaID); + } + + // The viewID received as an argument, is the ID of the client's view, which + // does not exist on the master. So we ignore this argument and open a new + // view instead. + CheckUtil.checkState(lockAreaID.equals(lockArea.getDurableLockingID()), "lockAreaID has incorrect value"); + + return view; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockNotificationRequest.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockNotificationRequest.java new file mode 100644 index 0000000000..17314e9532 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockNotificationRequest.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class LockNotificationRequest extends CDOServerRequest +{ + private CDOLockChangeInfo lockChangeInfo; + + public LockNotificationRequest(CDOServerProtocol serverProtocol, CDOLockChangeInfo lockChangeInfo) + { + super(serverProtocol, CDOProtocolConstants.SIGNAL_LOCK_NOTIFICATION); + this.lockChangeInfo = lockChangeInfo; + } + + @Override + protected void requesting(CDODataOutput out) throws IOException + { + out.writeCDOLockChangeInfo(lockChangeInfo); + } +} 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 236c74455e..b61cc1cf8b 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 @@ -13,24 +13,20 @@ package org.eclipse.emf.cdo.server.internal.net4j.protocol; import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; -import org.eclipse.emf.cdo.common.revision.CDORevision; 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.emf.cdo.spi.server.InternalRepository; +import org.eclipse.emf.cdo.spi.server.InternalView; -import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; -import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException; + +import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult; import java.io.IOException; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -39,138 +35,63 @@ import java.util.List; */ public class LockObjectsIndication extends CDOServerWriteIndication { - private List staleRevisions = new LinkedList(); - - private boolean timedOut; - - private boolean passiveUpdatesEnabled; - - private long requiredTimestamp; - - private boolean staleNoUpdate; + private LockObjectsResult result; public LockObjectsIndication(CDOServerProtocol protocol) { super(protocol, CDOProtocolConstants.SIGNAL_LOCK_OBJECTS); } + protected LockObjectsIndication(CDOServerProtocol protocol, short signalID) + { + super(protocol, signalID); + } + @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(); CDOBranch viewedBranch = in.readCDOBranch(); int nRevisions = in.readInt(); - CDORevisionKey[] revKeys = new CDORevisionKey[nRevisions]; + List revisionKeys = new LinkedList(); for (int i = 0; i < nRevisions; i++) { - revKeys[i] = in.readCDORevisionKey(); + revisionKeys.add(in.readCDORevisionKey()); } - List objectsToBeLocked = new ArrayList(); - boolean isSupportingBranches = getRepository().isSupportingBranches(); - for (CDORevisionKey revKey : revKeys) - { - CDOID id = revKey.getID(); - if (isSupportingBranches) - { - objectsToBeLocked.add(CDOIDUtil.createIDAndBranch(id, viewedBranch)); - } - else - { - objectsToBeLocked.add(id); - } - } - - IView view = session.getView(viewID); - InternalLockManager lockManager = getRepository().getLockManager(); - - try - { - lockManager.lock(true, lockType, view, objectsToBeLocked, timeout); - } - catch (TimeoutRuntimeException ex) - { - timedOut = true; - return; - } - catch (InterruptedException ex) - { - throw WrappedException.wrap(ex); - } - - try - { - for (CDORevisionKey revKey : revKeys) - { - checkStale(viewedBranch, revKey); - } - } - catch (IllegalArgumentException ex) - { - lockManager.unlock(true, lockType, view, objectsToBeLocked); - throw ex; - } - - // 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) - { - lockManager.unlock(true, lockType, view, objectsToBeLocked); - } + InternalRepository repository = getRepository(); + IView view = getView(viewID, viewedBranch); + result = repository.lock((InternalView)view, lockType, revisionKeys, viewedBranch, timeout); } - @Override - protected void responding(CDODataOutput out) throws IOException + protected IView getView(int viewID, CDOBranch viewedBranch) { - 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) - { - out.writeInt(staleRevisions.size()); - for (CDORevisionKey staleRevision : staleRevisions) - { - out.writeCDORevisionKey(staleRevision); - } - } - } + return getSession().getView(viewID); } - private void checkStale(CDOBranch viewedBranch, CDORevisionKey revKey) + @Override + protected void responding(CDODataOutput out) throws IOException { - CDOID id = revKey.getID(); - InternalCDORevision rev = getRepository().getRevisionManager().getRevision(id, viewedBranch.getHead(), - CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, true); - - if (rev == null) + out.writeBoolean(result.isSuccessful()); + out.writeBoolean(result.isTimedOut()); + out.writeBoolean(result.isWaitForUpdate()); + out.writeLong(result.getRequiredTimestamp()); + + CDORevisionKey[] staleRevisions = result.getStaleRevisions(); + out.writeInt(staleRevisions.length); + for (CDORevisionKey revKey : staleRevisions) { - throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id, - viewedBranch)); + out.writeCDORevisionKey(revKey); } - if (!revKey.equals(rev)) + CDOLockState[] newLockStates = result.getNewLockStates(); + out.writeInt(newLockStates.length); + for (CDOLockState lockState : newLockStates) { - staleRevisions.add(revKey); - requiredTimestamp = Math.max(requiredTimestamp, rev.getTimeStamp()); + out.writeCDOLockState(lockState); } } } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockStateIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockStateIndication.java new file mode 100644 index 0000000000..2ac03fbbcb --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockStateIndication.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.lock.CDOLockState; +import org.eclipse.emf.cdo.common.lock.CDOLockUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.server.IView; +import org.eclipse.emf.cdo.spi.server.InternalLockManager; +import org.eclipse.emf.cdo.spi.server.InternalView; + +import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class LockStateIndication extends CDOServerReadIndication +{ + private CDOLockState[] cdoLockStates; + + public LockStateIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_LOCK_STATE); + } + + @Override + protected void indicating(CDODataInput in) throws IOException + { + int viewID = in.readInt(); + InternalView view = getSession().getView(viewID); + if (view == null) + { + throw new IllegalStateException("View not found"); + } + + InternalLockManager lockMgr = getRepository().getLockManager(); + + int n = in.readInt(); + cdoLockStates = new CDOLockState[n]; + for (int i = 0; i < n; i++) + { + Object key = indicatingCDOID(in, view.getBranch()); + LockState lockState = lockMgr.getLockState(key); + if (lockState != null) + { + cdoLockStates[i] = CDOLockUtil.createLockState(lockState); + } + else + { + cdoLockStates[i] = CDOLockUtil.createLockState(key); + } + } + } + + private Object indicatingCDOID(CDODataInput in, CDOBranch viewedBranch) throws IOException + { + CDOID id = in.readCDOID(); + if (getRepository().isSupportingBranches()) + { + return CDOIDUtil.createIDAndBranch(id, viewedBranch); + } + + return id; + } + + @Override + protected void responding(CDODataOutput out) throws IOException + { + out.writeInt(cdoLockStates.length); + for (CDOLockState lockState : cdoLockStates) + { + out.writeCDOLockState(lockState); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenViewIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenViewIndication.java index d55c50c5c2..25c515f45c 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenViewIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenViewIndication.java @@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.spi.server.InternalLockManager; import org.eclipse.emf.cdo.spi.server.InternalSession; +import org.eclipse.emf.cdo.spi.server.InternalView; import java.io.IOException; @@ -25,7 +26,7 @@ import java.io.IOException; */ public class OpenViewIndication extends CDOServerReadIndication { - private CDOBranchPoint result; + private InternalView newView; private String message; @@ -47,11 +48,11 @@ public class OpenViewIndication extends CDOServerReadIndication CDOBranchPoint branchPoint = in.readCDOBranchPoint(); if (readOnly) { - session.openView(viewID, branchPoint); + newView = session.openView(viewID, branchPoint); } else { - session.openTransaction(viewID, branchPoint); + newView = session.openTransaction(viewID, branchPoint); } } else @@ -61,7 +62,7 @@ public class OpenViewIndication extends CDOServerReadIndication try { String durableLockingID = in.readString(); - result = lockManager.openView(session, viewID, readOnly, durableLockingID); + newView = (InternalView)lockManager.openView(session, viewID, readOnly, durableLockingID); } catch (LockAreaNotFoundException ex) { @@ -77,10 +78,10 @@ public class OpenViewIndication extends CDOServerReadIndication @Override protected void responding(CDODataOutput out) throws IOException { - if (result != null) + if (newView != null) { out.writeBoolean(true); - out.writeCDOBranchPoint(result); + out.writeCDOBranchPoint(newView); } else { diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockDelegationIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockDelegationIndication.java new file mode 100644 index 0000000000..a33b2606fe --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockDelegationIndication.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Caspar De Groot - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.server.IView; +import org.eclipse.emf.cdo.spi.server.InternalLockManager; +import org.eclipse.emf.cdo.spi.server.InternalSession; +import org.eclipse.emf.cdo.spi.server.InternalView; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class UnlockDelegationIndication extends UnlockObjectsIndication +{ + private InternalView view; + + private String lockAreaID; + + public UnlockDelegationIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_UNLOCK_OBJECTS); + } + + @Override + protected void indicating(CDODataInput in) throws IOException + { + lockAreaID = in.readString(); + super.indicating(in); + } + + @Override + protected void responding(CDODataOutput out) throws IOException + { + try + { + super.responding(out); + } + finally + { + view.close(); + } + } + + @Override + protected IView getView(int viewID) + { + InternalLockManager lockManager = getRepository().getLockManager(); + InternalSession session = getSession(); + view = (InternalView)lockManager.openView(session, InternalSession.TEMP_VIEW_ID, true, lockAreaID); + return view; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java index 7c01c31d89..a945056014 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java @@ -11,20 +11,21 @@ */ package org.eclipse.emf.cdo.server.internal.net4j.protocol; -import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.server.IView; -import org.eclipse.emf.cdo.spi.server.InternalLockManager; import org.eclipse.emf.cdo.spi.server.InternalRepository; +import org.eclipse.emf.cdo.spi.server.InternalView; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; +import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult; + import java.io.IOException; -import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; /** @@ -32,11 +33,18 @@ import java.util.List; */ public class UnlockObjectsIndication extends CDOServerWriteIndication { + private UnlockObjectsResult result; + public UnlockObjectsIndication(CDOServerProtocol protocol) { super(protocol, CDOProtocolConstants.SIGNAL_UNLOCK_OBJECTS); } + protected UnlockObjectsIndication(CDOServerProtocol protocol, short signalID) + { + super(protocol, signalID); + } + @Override protected void indicating(CDODataInput in) throws IOException { @@ -45,33 +53,37 @@ public class UnlockObjectsIndication extends CDOServerWriteIndication int size = in.readInt(); InternalRepository repository = getRepository(); - InternalLockManager lockManager = repository.getLockManager(); - IView view = getSession().getView(viewID); + IView view = getView(viewID); if (size == CDOProtocolConstants.RELEASE_ALL_LOCKS) { - lockManager.unlock(true, view); + result = repository.unlock((InternalView)view, null, null); } else { - boolean supportingBranches = repository.isSupportingBranches(); - CDOBranch branch = view.getBranch(); - - List keys = new ArrayList(size); + List objectIDs = new LinkedList(); for (int i = 0; i < size; i++) { - CDOID id = in.readCDOID(); - Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id; - keys.add(key); + objectIDs.add(in.readCDOID()); } - lockManager.unlock(true, lockType, view, keys); + result = repository.unlock((InternalView)view, lockType, objectIDs); } } @Override protected void responding(CDODataOutput out) throws IOException { - out.writeBoolean(true); + CDOLockState[] newLockStates = result.getNewLockStates(); + out.writeInt(newLockStates.length); + for (CDOLockState state : newLockStates) + { + out.writeCDOLockState(state); + } + } + + protected IView getView(int viewID) + { + return getSession().getView(viewID); } } -- cgit v1.2.3