summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2011-09-05 07:07:38 (EDT)
committerCaspar De Groot2011-09-05 07:07:38 (EDT)
commit6f2beae5f3a603c684e37bcfe9eb1df99cdb9e94 (patch)
tree409af9eedae87ea111c08a7b5b787eaf479d6c4e
parent760274f256e688aa3afda4546bb91f737c6f307d (diff)
downloadcdo-6f2beae5f3a603c684e37bcfe9eb1df99cdb9e94.zip
cdo-6f2beae5f3a603c684e37bcfe9eb1df99cdb9e94.tar.gz
cdo-6f2beae5f3a603c684e37bcfe9eb1df99cdb9e94.tar.bz2
[351912] Lock coordination with SynchronizableRepositories
https://bugs.eclipse.org/bugs/show_bug.cgi?id=351912
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java44
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java72
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java42
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java86
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java97
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java25
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java8
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java44
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java18
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java27
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java30
32 files changed, 442 insertions, 150 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java
index 8bea47f..09cee9b 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java
@@ -169,5 +169,19 @@ public interface CDOCommonSession extends IUserAware, IOptionsContainer, Closeab
public PassiveUpdateMode getNewMode();
}
+
+ /**
+ * An {@link IOptionsEvent options event} fired when the {@link LockNotificationMode lock notification mode} of a
+ * CDO session has changed.
+ *
+ * @author Caspar De Groot
+ * @since 4.1
+ */
+ public interface LockNotificationModeEvent extends IOptionsEvent
+ {
+ public LockNotificationMode getOldMode();
+
+ public LockNotificationMode getNewMode();
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
index d24ec88..fc6f689 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
@@ -86,6 +86,7 @@ public interface CDOCommonView extends CDOBranchPoint, CDORevisionProvider, IOpt
*/
public interface LockNotificationEvent extends IOptionsEvent
{
+ boolean getEnabled();
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java
index 118f973..91b3cc3 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java
@@ -11,6 +11,9 @@
package org.eclipse.emf.cdo.common.lock;
/**
+ * A call-back interface that indicates the ability to <i>handle</i> {@link CDOLockChangeInfo lock-change infos} that
+ * are passed from other entities.
+ *
* @author Caspar De Groot
* @since 4.1
*/
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java
index 430e020..919cd41 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java
@@ -68,9 +68,12 @@ public interface IDurableLockingManager
public Map<CDOID, LockGrade> getLocks();
/**
+ * Returns <code>true</code> if this instance represents a lock area that is known to be missing (not present) on a
+ * master server. (Relevant only in a replicating configuration.)
+ *
* @since 4.1
*/
- public boolean isDeleted();
+ public boolean isMissing();
/**
* A call-back interface for <em>handling</em> {@link LockArea lock area} objects.
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
index af623ca..1c2644d 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
@@ -242,6 +242,11 @@ public interface CDOProtocolConstants
*/
public static final short SIGNAL_ENABLE_LOCK_NOTIFICATION = 53;
+ /**
+ * @since 4.1
+ */
+ public static final short SIGNAL_SET_LOCK_NOTIFICATION_MODE = 54;
+
// //////////////////////////////////////////////////////////////////////
// Session Refresh
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java
index 4baa364..3bbb9e5 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java
@@ -39,7 +39,7 @@ public class CDOLockAreaImpl implements LockArea
private final Map<CDOID, LockGrade> locks;
- private final boolean deleted;
+ private final boolean missing;
public CDOLockAreaImpl(String durableLockingID, String userID, CDOBranchPoint branchPoint, boolean readOnly,
Map<CDOID, LockGrade> locks)
@@ -49,7 +49,7 @@ public class CDOLockAreaImpl implements LockArea
this.branchPoint = branchPoint;
this.readOnly = readOnly;
this.locks = locks;
- deleted = false;
+ missing = false;
}
public CDOLockAreaImpl(String durableLockingID)
@@ -59,7 +59,7 @@ public class CDOLockAreaImpl implements LockArea
branchPoint = null;
readOnly = false;
locks = null;
- deleted = true;
+ missing = true;
}
public String getDurableLockingID()
@@ -99,8 +99,8 @@ public class CDOLockAreaImpl implements LockArea
durableLockingID, userID, branchPoint, readOnly, locks);
}
- public boolean isDeleted()
+ public boolean isMissing()
{
- return deleted;
+ return missing;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
index 956ed51..20491c8 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
@@ -525,4 +525,9 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO
{
send(new EnableLockNotificationRequest(this, viewID, on));
}
+
+ public void setLockNotificationMode(LockNotificationMode mode)
+ {
+ send(new SetLockNotificationModeRequest(this, mode));
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java
index b01f0a0..1b6b9b5 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java
@@ -84,6 +84,8 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult>
staleRevisions[i] = in.readCDORevisionKey();
}
+ long timestamp = in.readLong();
+
int n = in.readInt();
CDOLockState[] newLockStates = new CDOLockState[n];
for (int i = 0; i < n; i++)
@@ -91,6 +93,7 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult>
newLockStates[i] = in.readCDOLockState();
}
- return new LockObjectsResult(succesful, timeout, waitForUpdate, requiredTimestamp, staleRevisions, newLockStates);
+ return new LockObjectsResult(succesful, timeout, waitForUpdate, requiredTimestamp, staleRevisions, newLockStates,
+ timestamp);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java
index 156fc10..d919a00 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java
@@ -68,11 +68,11 @@ public class ReplicateRepositoryRequest extends CDOClientRequest<Boolean>
break;
case CDOProtocolConstants.REPLICATE_LOCKAREA:
- boolean deleted = !in.readBoolean();
- if (deleted)
+ boolean missing = !in.readBoolean();
+ if (missing)
{
- String deletedLockAreaID = in.readString();
- LockArea area = CDOLockUtil.createLockArea(deletedLockAreaID);
+ String missingLockAreaID = in.readString();
+ LockArea area = CDOLockUtil.createLockArea(missingLockAreaID);
context.handleLockArea(area);
}
else
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java
new file mode 100644
index 0000000..688cdb2
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java
@@ -0,0 +1,44 @@
+/**
+ * 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.internal.net4j.protocol;
+
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
+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 java.io.IOException;
+
+/**
+ * @author Caspar De Groot
+ */
+public class SetLockNotificationModeRequest extends CDOClientRequest<Boolean>
+{
+ private LockNotificationMode mode;
+
+ public SetLockNotificationModeRequest(CDOClientProtocol protocol, LockNotificationMode mode)
+ {
+ super(protocol, CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE);
+ this.mode = mode;
+ }
+
+ @Override
+ protected void requesting(CDODataOutput out) throws IOException
+ {
+ out.writeEnum(mode);
+ }
+
+ @Override
+ protected Boolean confirming(CDODataInput in) throws IOException
+ {
+ return in.readBoolean();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java
index 0eefb36..1dcc86c 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java
@@ -90,12 +90,13 @@ public class UnlockObjectsRequest extends CDOClientRequest<UnlockObjectsResult>
@Override
protected UnlockObjectsResult confirming(CDODataInput in) throws IOException
{
+ long timestamp = in.readLong();
int n = in.readInt();
CDOLockState[] newLockStates = new CDOLockState[n];
for (int i = 0; i < n; i++)
{
newLockStates[i] = in.readCDOLockState();
}
- return new UnlockObjectsResult(newLockStates);
+ return new UnlockObjectsResult(newLockStates, timestamp);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
index bc1481a..42aca92 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
@@ -1301,9 +1301,10 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
return manager.createLockArea(this, durableLockingID, userID, branchPoint, readOnly, locks);
}
- public void updateLockArea(LockArea lockArea)
+ public void updateLockArea(LockArea area)
{
- throw new RuntimeException("TODO (CD)"); // TODO (CD)
+ DurableLockingManager manager = getStore().getDurableLockingManager();
+ manager.updateLockArea(this, area);
}
public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
index 1e21836..7fbd726 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
@@ -151,30 +151,7 @@ public class DurableLockingManager extends Lifecycle
if (!locks.isEmpty())
{
- try
- {
- stmt = statementCache.getPreparedStatement(sqlInsertLock, ReuseProbability.MEDIUM);
- stmt.setString(1, durableLockingID);
-
- for (Entry<CDOID, LockGrade> entry : locks.entrySet())
- {
- CDOID id = entry.getKey();
- int grade = entry.getValue().getValue();
-
- idHandler.setCDOID(stmt, 2, id);
- stmt.setInt(3, grade);
-
- DBUtil.update(stmt, true);
- }
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
+ insertLocks(accessor, durableLockingID, locks);
}
accessor.getConnection().commit();
@@ -187,6 +164,37 @@ public class DurableLockingManager extends Lifecycle
}
}
+ private void insertLocks(DBStoreAccessor accessor, String durableLockingID, Map<CDOID, LockGrade> locks)
+ {
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(sqlInsertLock, ReuseProbability.MEDIUM);
+ stmt.setString(1, durableLockingID);
+
+ for (Entry<CDOID, LockGrade> entry : locks.entrySet())
+ {
+ CDOID id = entry.getKey();
+ int grade = entry.getValue().getValue();
+
+ idHandler.setCDOID(stmt, 2, id);
+ stmt.setInt(3, grade);
+
+ DBUtil.update(stmt, true);
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
public LockArea getLockArea(DBStoreAccessor accessor, String durableLockingID) throws LockAreaNotFoundException
{
IPreparedStatementCache statementCache = accessor.getStatementCache();
@@ -300,6 +308,22 @@ public class DurableLockingManager extends Lifecycle
}
}
+ public void updateLockArea(DBStoreAccessor accessor, LockArea area)
+ {
+ try
+ {
+ String areaID = area.getDurableLockingID();
+ unlockWithoutCommit(accessor, areaID);
+ insertLocks(accessor, areaID, area.getLocks());
+
+ accessor.getConnection().commit();
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ }
+
public void lock(DBStoreAccessor accessor, String durableLockingID, LockType type,
Collection<? extends Object> objectsToLock)
{
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 c3c7d4f..30281c9 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
@@ -320,6 +320,9 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement
case CDOProtocolConstants.SIGNAL_ENABLE_LOCK_NOTIFICATION:
return new EnableLockNotificationIndication(this);
+ case CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE:
+ return new SetLockNotificationModeIndication(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/LockObjectsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java
index 4484526..3773c05 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
@@ -85,6 +85,8 @@ public class LockObjectsIndication extends CDOServerWriteIndication
out.writeCDORevisionKey(revKey);
}
+ out.writeLong(result.getTimestamp());
+
CDOLockState[] newLockStates = result.getNewLockStates();
out.writeInt(newLockStates.length);
for (CDOLockState lockState : newLockStates)
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java
new file mode 100644
index 0000000..2409224
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java
@@ -0,0 +1,42 @@
+/**
+ * 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.CDOCommonSession.Options.LockNotificationMode;
+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 java.io.IOException;
+
+/**
+ * @author Caspar De Groot
+ */
+public class SetLockNotificationModeIndication extends CDOServerReadIndication
+{
+ public SetLockNotificationModeIndication(CDOServerProtocol protocol)
+ {
+ super(protocol, CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE);
+ }
+
+ @Override
+ protected void indicating(CDODataInput in) throws IOException
+ {
+ LockNotificationMode mode = in.readEnum(LockNotificationMode.class);
+ getSession().setLockNotificationMode(mode);
+ }
+
+ @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/UnlockObjectsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java
index a945056..e4cc3a1 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
@@ -74,6 +74,7 @@ public class UnlockObjectsIndication extends CDOServerWriteIndication
@Override
protected void responding(CDODataOutput out) throws IOException
{
+ out.writeLong(result.getTimestamp());
CDOLockState[] newLockStates = result.getNewLockStates();
out.writeInt(newLockStates.length);
for (CDOLockState state : newLockStates)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
index 19d2094..26ba1ad 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
@@ -574,34 +574,14 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
*/
private final class DurableLockLoader implements LockArea.Handler
{
- // Note (CD) This field is a sneaky way of avoiding more API changes.
- // The view should properly be an argument on #handleLockArea(LockArea)
- private IView view;
-
public DurableLockLoader()
{
}
- public DurableLockLoader(IView view)
- {
- this.view = view;
- }
-
- private IView getView(LockArea area)
- {
- if (view != null)
- {
- return view;
- }
-
- DurableView view = new DurableView(area.getDurableLockingID());
- durableViews.put(area.getDurableLockingID(), view);
- return view;
- }
-
public boolean handleLockArea(LockArea area)
{
- IView view = getView(area);
+ IView view = durableViews.get(area.getDurableLockingID());
+ CheckUtil.checkNull(view, "view");
Collection<Object> readLocks = new ArrayList<Object>();
Collection<Object> writeLocks = new ArrayList<Object>();
@@ -658,44 +638,54 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
return grade;
}
- public void updateLockArea(LockArea lockArea)
+ private IView getOrCreateView(String lockAreaID)
{
- DurableLocking2 accessor = getDurableLocking2();
- if (lockArea.isDeleted())
+ IView view = openViews.get(lockAreaID);
+ if (view == null)
{
- accessor.deleteLockArea(lockArea.getDurableLockingID());
+ view = durableViews.get(lockAreaID);
}
- else
+ if (view == null)
{
- accessor.updateLockArea(lockArea);
+ view = new DurableView(lockAreaID);
+ durableViews.put(lockAreaID, (DurableView)view);
}
+ return view;
+ }
- IView view = openViews.get(lockArea.getDurableLockingID());
- if (view == null)
+ private LockArea getLockAreaNoEx(String durableLockingID)
+ {
+ try
+ {
+ return getLockArea(durableLockingID);
+ }
+ catch (LockAreaNotFoundException e)
{
- view = durableViews.get(lockArea.getDurableLockingID());
+ return null;
+ }
+ }
- // If we already have this durableView, we remove all the locks first...
- if (view != null)
- {
- unlock2(view);
- }
+ public void updateLockArea(LockArea lockArea)
+ {
+ String durableLockingID = lockArea.getDurableLockingID();
+ DurableLocking2 accessor = getDurableLocking2();
- // ...then reload from the new lockArea
- //
- if (lockArea.isDeleted())
+ if (lockArea.isMissing())
+ {
+ LockArea localLockArea = getLockAreaNoEx(durableLockingID);
+ if (localLockArea != null && localLockArea.getLocks().size() > 0)
{
- DurableView deletedView = durableViews.remove(lockArea.getDurableLockingID());
+ accessor.deleteLockArea(durableLockingID);
+ DurableView deletedView = durableViews.remove(durableLockingID);
CheckUtil.checkNull(deletedView, "deletedView");
}
- else
- {
- DurableLockLoader handler = new DurableLockLoader(view);
- handler.handleLockArea(lockArea);
- }
-
- view = durableViews.get(lockArea.getDurableLockingID());
- CheckUtil.checkNull(view, "view");
+ }
+ else
+ {
+ accessor.updateLockArea(lockArea);
+ IView view = getOrCreateView(durableLockingID);
+ unlock2(view);
+ new DurableLockLoader().handleLockArea(lockArea);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index 2b35f7b..70dacf0 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -1150,7 +1150,7 @@ public class Repository extends Container<Object> implements InternalRepository
public String[] getLockAreaIDs()
{
- return null; // TODO (CD)
+ return null; // TODO (CD) Raw replication of lockAreas
}
};
}
@@ -1382,7 +1382,7 @@ public class Repository extends Container<Object> implements InternalRepository
}
catch (TimeoutRuntimeException ex)
{
- return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0]);
+ return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
}
catch (InterruptedException ex)
{
@@ -1400,14 +1400,16 @@ public class Repository extends Container<Object> implements InternalRepository
if (staleNoUpdate)
{
lockManager.unlock2(true, type, view, lockables);
- return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0]);
+ return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0],
+ getTimeStamp());
}
CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
boolean waitForUpdate = staleRevisionsArray.length > 0;
- return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates);
+ return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates,
+ getTimeStamp());
}
private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
@@ -1499,10 +1501,11 @@ public class Repository extends Container<Object> implements InternalRepository
newLockStates = lockManager.unlock2(true, lockType, view, unlockables);
}
+ long timestamp = getTimeStamp();
CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
- return new UnlockObjectsResult(cdoLockStates);
+ return new UnlockObjectsResult(cdoLockStates, timestamp);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
index ef6ee54..bb0205d 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
@@ -77,8 +77,7 @@ public class Session extends Container<IView> implements InternalSession
private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
- private LockNotificationMode lockNotificationMode = LockNotificationMode.ALWAYS; // TODO (CD) Default should be
- // PER_VIEW
+ private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
private long lastUpdateTime;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java
index dd7471a..531f5a9 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.cdo.internal.server.embedded;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
@@ -165,6 +166,11 @@ public class EmbeddedClientSessionProtocol extends Lifecycle implements CDOSessi
throw new UnsupportedOperationException();
}
+ public void setLockNotificationMode(LockNotificationMode mode)
+ {
+ throw new UnsupportedOperationException();
+ }
+
public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex,
int fromIndex, int toIndex)
{
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
index dfdb97e..96f26ac 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
@@ -790,7 +790,6 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader, Du
{
String userID = area.getUserID();
if (userID == null || userID.startsWith(userIDPrefix))
- // if (userID != null && userID.startsWith(userIDPrefix)) // TODO (CD) Used to be this. Any breakage?
{
if (!handler.handleLockArea(area))
{
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java
index a2fe4df..dfb44b8 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java
@@ -506,25 +506,64 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
}
}
- /**
- * @author Eike Stepper
- */
- private final class CommitRunnable extends QueueRunnable
+ private final class CommitRunnable extends RetryingRunnable
{
private CDOCommitInfo commitInfo;
- private List<Exception> failedRuns;
-
public CommitRunnable(CDOCommitInfo commitInfo)
{
this.commitInfo = commitInfo;
}
+ @Override
+ protected void doRun()
+ {
+ localRepository.handleCommitInfo(commitInfo);
+ }
+
+ @Override
+ public int compareTo(QueueRunnable o)
+ {
+ int result = super.compareTo(o);
+ if (result == 0)
+ {
+ Long timeStamp = commitInfo.getTimeStamp();
+ Long timeStamp2 = ((CommitRunnable)o).commitInfo.getTimeStamp();
+ result = timeStamp < timeStamp2 ? -1 : timeStamp == timeStamp2 ? 0 : 1;
+ }
+
+ return result;
+ }
+
+ @Override
+ protected Integer getPriority()
+ {
+ return COMMIT_PRIORITY;
+ }
+
+ @Override
+ protected String getErrorMessage()
+ {
+ return "Replication of master commit failed:" + commitInfo;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private abstract class RetryingRunnable extends QueueRunnable
+ {
+ private List<Exception> failedRuns;
+
+ protected abstract void doRun();
+
+ protected abstract String getErrorMessage();
+
public void run()
{
try
{
- localRepository.handleCommitInfo(commitInfo);
+ doRun();
}
catch (Exception ex)
{
@@ -553,7 +592,7 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
{
try
{
- addWork(CommitRunnable.this);
+ addWork(this);
}
catch (Exception ex)
{
@@ -564,36 +603,16 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
}
else
{
- OM.LOG.error("Replication of master commit failed:" + commitInfo, ex);
+ OM.LOG.error(getErrorMessage(), ex);
}
}
}
-
- @Override
- public int compareTo(QueueRunnable o)
- {
- int result = super.compareTo(o);
- if (result == 0)
- {
- Long timeStamp = commitInfo.getTimeStamp();
- Long timeStamp2 = ((CommitRunnable)o).commitInfo.getTimeStamp();
- result = timeStamp < timeStamp2 ? -1 : timeStamp == timeStamp2 ? 0 : 1;
- }
-
- return result;
- }
-
- @Override
- protected Integer getPriority()
- {
- return COMMIT_PRIORITY;
- }
}
/**
* @author Caspar De Groot
*/
- private final class LocksRunnable extends QueueRunnable
+ private final class LocksRunnable extends RetryingRunnable
{
private CDOLockChangeInfo lockChangeInfo;
@@ -602,18 +621,20 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
this.lockChangeInfo = lockChangeInfo;
}
- public void run()
+ @Override
+ protected Integer getPriority()
+ {
+ return LOCKS_PRIORITY;
+ }
+
+ @Override
+ protected void doRun()
{
try
{
StoreThreadLocal.setSession(localRepository.getReplicatorSession());
localRepository.handleLockChangeInfo(lockChangeInfo);
}
- catch (Exception ex)
- {
- // TODO (CD) Retry as for commit?
- ex.printStackTrace();
- }
finally
{
StoreThreadLocal.release();
@@ -621,9 +642,9 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
}
@Override
- protected Integer getPriority()
+ protected String getErrorMessage()
{
- return LOCKS_PRIORITY;
+ return "Replication of master lock changes failed:" + lockChangeInfo;
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
index 06e640b..2276dc9 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
@@ -192,7 +192,24 @@ public abstract class SynchronizableRepository extends Repository.Default implem
public String[] getLockAreaIDs()
{
- return new String[0]; // TODO (CD)
+ try
+ {
+ StoreThreadLocal.setSession(replicatorSession);
+ final List<String> areaIDs = new LinkedList<String>();
+ getLockManager().getLockAreas(null, new LockArea.Handler()
+ {
+ public boolean handleLockArea(LockArea area)
+ {
+ areaIDs.add(area.getDurableLockingID());
+ return true;
+ }
+ });
+ return areaIDs.toArray(new String[areaIDs.size()]);
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
}
public void handleBranch(CDOBranch branch)
@@ -271,7 +288,11 @@ public abstract class SynchronizableRepository extends Repository.Default implem
if (lockChangeInfo.getOperation() == Operation.LOCK)
{
- long timeout = 10000; // TODO (CD)
+ // If we can't lock immediately, there's a conflict, which means we're in big
+ // trouble: somehow locks were obtained on the clone but not on the master. What to do?
+ // TODO (CD) Consider this problem further
+ //
+ long timeout = 0;
super.lock(view, lockType, lockables, null, timeout);
}
else if (lockChangeInfo.getOperation() == Operation.UNLOCK)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java
index 1db5bfc..40c3826 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java
@@ -101,7 +101,7 @@ public class DurableLockArea implements LockArea
/**
* @since 4.1
*/
- public boolean isDeleted()
+ public boolean isMissing()
{
return false;
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java
index 69d2d7f..d57d24e 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java
@@ -71,7 +71,7 @@ public class FailoverTest extends AbstractSyncingTest
{
CDOSession session = openSession("master");
CDOTransaction transaction = session.openTransaction();
- CDOResource resource = transaction.createResource(getResourcePath("/my/resource"));
+ CDOResource resource = transaction.createResource(getResourcePath("test"));
Company company = getModel1Factory().createCompany();
company.setName("Test");
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java
index 90faae7..7698905 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java
@@ -14,6 +14,14 @@ import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.view.CDOView;
/**
+ * A {@link CDOSessionEvent session event} fired when lock-change notifications are received from a remote repository.
+ * For this event to be fired,
+ * {@link CDOSession.Options#setLockNotificationMode(org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode)
+ * the lock notification mode} must either be set to ALWAYS, or it must be set to IF_REQUIRED_BY_VIEWS <i>and</i> at
+ * least one of this sessions' views must have
+ * {@link org.eclipse.emf.cdo.common.CDOCommonView.Options#setLockNotificationEnabled(boolean) its lock-notification
+ * enablement} set to <code>true</code>.
+ *
* @author Caspar De Groot
* @since 4.1
*/
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index 4e5b154..6153b50 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -1445,6 +1445,23 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
{
+ checkArg(lockNotificationMode, "lockNotificationMode"); //$NON-NLS-1$
+ if (this.lockNotificationMode != lockNotificationMode)
+ {
+ LockNotificationMode oldMode = this.lockNotificationMode;
+ this.lockNotificationMode = lockNotificationMode;
+ CDOSessionProtocol protocol = getSessionProtocol();
+ if (protocol != null)
+ {
+ protocol.setLockNotificationMode(lockNotificationMode);
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new LockNotificationModeEventImpl(oldMode, lockNotificationMode), listeners);
+ }
+ }
+ }
this.lockNotificationMode = lockNotificationMode;
}
@@ -1589,6 +1606,33 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
}
/**
+ * @author Caspar De Groot
+ */
+ private final class LockNotificationModeEventImpl extends OptionsEvent implements LockNotificationModeEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private LockNotificationMode oldMode, newMode;
+
+ public LockNotificationModeEventImpl(LockNotificationMode oldMode, LockNotificationMode newMode)
+ {
+ super(OptionsImpl.this);
+ this.oldMode = oldMode;
+ this.newMode = newMode;
+ }
+
+ public LockNotificationMode getOldMode()
+ {
+ return oldMode;
+ }
+
+ public LockNotificationMode getNewMode()
+ {
+ return newMode;
+ }
+ }
+
+ /**
* @author Eike Stepper
*/
private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java
index c88715a..83cb15a 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.internal.cdo.session;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
@@ -735,6 +736,23 @@ public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionPr
}
}
+ public void setLockNotificationMode(LockNotificationMode mode)
+ {
+ int attempt = 0;
+ for (;;)
+ {
+ try
+ {
+ delegate.setLockNotificationMode(mode);
+ return;
+ }
+ catch (Exception ex)
+ {
+ handleException(++attempt, ex);
+ }
+ }
+ }
+
public RefreshSessionResult refresh(long lastUpdateTime,
Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions, int initialChunkSize,
boolean enablePassiveUpdates)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
index 73d8546..b6e535b 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
@@ -2653,7 +2653,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
CDOLockState[] newLockStates = result.getNewLockStates();
if (newLockStates != null)
{
- updateAndNotifyLockStates(Operation.UNLOCK, null, newLockStates);
+ updateAndNotifyLockStates(Operation.UNLOCK, null, result.getTimeStamp(), newLockStates);
}
}
catch (RuntimeException ex)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index 5f6be8a..b1dc5c1 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -297,7 +297,7 @@ public class CDOViewImpl extends AbstractCDOView
}
// Update the lock states in this view
- updateAndNotifyLockStates(Operation.LOCK, lockType, result.getNewLockStates());
+ updateAndNotifyLockStates(Operation.LOCK, lockType, result.getTimestamp(), result.getNewLockStates());
if (result.isWaitForUpdate())
{
@@ -312,10 +312,10 @@ public class CDOViewImpl extends AbstractCDOView
}
}
- protected void updateAndNotifyLockStates(Operation op, LockType type, CDOLockState[] newLockStates)
+ protected void updateAndNotifyLockStates(Operation op, LockType type, long timestamp, CDOLockState[] newLockStates)
{
updateLockStates(newLockStates);
- notifyOtherViewsAboutLockChanges(op, type, newLockStates);
+ notifyOtherViewsAboutLockChanges(op, type, timestamp, newLockStates);
}
/**
@@ -347,18 +347,17 @@ public class CDOViewImpl extends AbstractCDOView
/**
* Notifies other views of lock changes performed in this view
*/
- private void notifyOtherViewsAboutLockChanges(Operation op, LockType type, CDOLockState[] lockStates)
+ private void notifyOtherViewsAboutLockChanges(Operation op, LockType type, long timestamp, CDOLockState[] lockStates)
{
if (lockStates.length > 0)
{
- CDOLockChangeInfo lockChangeInfo = makeLockChangeInfo(op, type, lockStates);
+ CDOLockChangeInfo lockChangeInfo = makeLockChangeInfo(op, type, timestamp, lockStates);
getSession().handleLockNotification(lockChangeInfo, this);
}
}
- private CDOLockChangeInfo makeLockChangeInfo(Operation op, LockType type, CDOLockState[] newLockStates)
+ private CDOLockChangeInfo makeLockChangeInfo(Operation op, LockType type, long timestamp, CDOLockState[] newLockStates)
{
- long timestamp = 0L; // TODO (CD) Get rid of timestamps; replace with sequential number
return CDOLockUtil.createLockChangeInfo(timestamp, this, getBranch(), op, type, newLockStates);
}
@@ -434,7 +433,7 @@ public class CDOViewImpl extends AbstractCDOView
CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
UnlockObjectsResult result = sessionProtocol.unlockObjects2(this, objectIDs, lockType);
- updateAndNotifyLockStates(Operation.UNLOCK, lockType, result.getNewLockStates());
+ updateAndNotifyLockStates(Operation.UNLOCK, lockType, result.getTimestamp(), result.getNewLockStates());
}
/**
@@ -1534,7 +1533,7 @@ public class CDOViewImpl extends AbstractCDOView
CDOSessionProtocol protocol = getSession().getSessionProtocol();
protocol.enableLockNotifications(viewID, enabled);
lockNotificationsEnabled = enabled;
- event = new LockNotificationEventImpl();
+ event = new LockNotificationEventImpl(enabled);
}
}
@@ -1831,9 +1830,17 @@ public class CDOViewImpl extends AbstractCDOView
{
private static final long serialVersionUID = 1L;
- public LockNotificationEventImpl()
+ private boolean enabled;
+
+ public LockNotificationEventImpl(boolean enabled)
{
super(OptionsImpl.this);
+ this.enabled = enabled;
+ }
+
+ public boolean getEnabled()
+ {
+ return enabled;
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java
index fdfc911..0dd3e0d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java
@@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOObjectReference;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
@@ -86,6 +87,11 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
public void setPassiveUpdateMode(PassiveUpdateMode mode);
/**
+ * @since 4.1
+ */
+ public void setLockNotificationMode(LockNotificationMode mode);
+
+ /**
* @since 3.0
*/
public RefreshSessionResult refresh(long lastUpdateTime,
@@ -807,6 +813,8 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
private long requiredTimestamp;
+ private long timestamp;
+
private CDORevisionKey[] staleRevisions;
private CDOLockState[] newLockStates;
@@ -815,14 +823,14 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
public LockObjectsResult(boolean successful, boolean timedOut, boolean waitForUpdate, long requiredTimestamp,
CDORevisionKey[] staleRevisions)
{
- throw new AssertionError("Deprecated"); // TODO (CD) What to do about this??
+ throw new AssertionError("Deprecated");
}
/**
* @since 4.1
*/
public LockObjectsResult(boolean successful, boolean timedOut, boolean waitForUpdate, long requiredTimestamp,
- CDORevisionKey[] staleRevisions, CDOLockState[] newLockStates)
+ CDORevisionKey[] staleRevisions, CDOLockState[] newLockStates, long timestamp)
{
this.successful = successful;
this.timedOut = timedOut;
@@ -830,6 +838,7 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
this.requiredTimestamp = requiredTimestamp;
this.staleRevisions = staleRevisions;
this.newLockStates = newLockStates;
+ this.timestamp = timestamp;
}
public boolean isSuccessful()
@@ -864,6 +873,14 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
{
return newLockStates;
}
+
+ /**
+ * @since 4.1
+ */
+ public long getTimestamp()
+ {
+ return timestamp;
+ }
}
/**
@@ -873,7 +890,9 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
{
private CDOLockState[] newLockStates;
- public UnlockObjectsResult(CDOLockState[] newLockStates)
+ private long timestamp;
+
+ public UnlockObjectsResult(CDOLockState[] newLockStates, long timestamp)
{
this.newLockStates = newLockStates;
}
@@ -882,5 +901,10 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
{
return newLockStates;
}
+
+ public long getTimestamp()
+ {
+ return timestamp;
+ }
}
}