summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2011-08-18 03:10:17 (EDT)
committerCaspar De Groot2011-08-18 03:10:17 (EDT)
commit4c7957d30a846d4d28186fb6239bb44d3e62067e (patch)
tree94fda2de39d68cec207cc5bf275ac21aa396ce8a
parent9e786153ab106d2fb6e33a7ce98a5cff3e459740 (diff)
downloadcdo-4c7957d30a846d4d28186fb6239bb44d3e62067e.zip
cdo-4c7957d30a846d4d28186fb6239bb44d3e62067e.tar.gz
cdo-4c7957d30a846d4d28186fb6239bb44d3e62067e.tar.bz2
[353691] Add lock notifications and lock caching
https://bugs.eclipse.org/bugs/show_bug.cgi?id=353691
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java139
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java19
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java75
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java1
5 files changed, 144 insertions, 103 deletions
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 f552982..e6fe19f 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
@@ -190,14 +190,17 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
}
@Deprecated
- public void unlock(boolean explicit, LockType type, IView view, Collection<? extends Object> objectsToUnlock)
+ public synchronized void unlock(boolean explicit, LockType type, IView view,
+ Collection<? extends Object> objectsToUnlock)
{
unlock2(explicit, type, view, objectsToUnlock);
}
- public List<LockState<Object, IView>> unlock2(boolean explicit, LockType type, IView view,
+ public synchronized List<LockState<Object, IView>> unlock2(boolean explicit, LockType type, IView view,
Collection<? extends Object> objectsToUnlock)
{
+ List<LockState<Object, IView>> newLockStates = super.unlock2(type, view, objectsToUnlock);
+
if (explicit)
{
String durableLockingID = view.getDurableLockingID();
@@ -208,16 +211,16 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
}
}
- return super.unlock2(type, view, objectsToUnlock);
+ return newLockStates;
}
@Deprecated
- public void unlock(boolean explicit, IView view)
+ public synchronized void unlock(boolean explicit, IView view)
{
unlock(explicit, view);
}
- public List<LockState<Object, IView>> unlock2(boolean explicit, IView view)
+ public synchronized List<LockState<Object, IView>> unlock2(boolean explicit, IView view)
{
if (explicit)
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java
index f9b8f6e..29f8312 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java
@@ -21,18 +21,13 @@ import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.util.TestListener2;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.view.CDOLocksChangedEvent;
import org.eclipse.emf.cdo.view.CDOView;
-import org.eclipse.net4j.util.event.IEvent;
-import org.eclipse.net4j.util.event.IListener;
-
-import java.util.LinkedList;
-import java.util.List;
-
/**
* @author Caspar De Groot
*/
@@ -91,123 +86,135 @@ public class LockingNotificationsTest extends AbstractLockingTest
{
CDOTransaction tx1 = session1.openTransaction();
CDOResource res1 = tx1.getOrCreateResource(getResourcePath("r1"));
- LockEventListener listener1 = new LockEventListener();
- tx1.addListener(listener1);
+ TestListener2 transactionListener = new TestListener2(CDOLocksChangedEvent.class);
+ tx1.addListener(transactionListener);
res1.getContents().clear();
- Company company1 = getModel1Factory().createCompany();
- res1.getContents().add(company1);
+ Company company = getModel1Factory().createCompany();
+ res1.getContents().add(company);
tx1.commit();
- LockEventListener listener2 = new LockEventListener();
- controlView.addListener(listener2);
+ TestListener2 controlViewListener = new TestListener2(CDOLocksChangedEvent.class);
+ controlView.addListener(controlViewListener);
+
+ CDOObject cdoCompany = CDOUtil.getCDOObject(company);
- CDOObject cdoCompany1 = CDOUtil.getCDOObject(company1);
+ CDOObject cdoCompanyInControlView = null;
+ if (mustReceiveNotifications)
+ {
+ cdoCompanyInControlView = controlView.getObject(cdoCompany.cdoID());
+ }
/* Test write lock */
- cdoCompany1.cdoWriteLock().lock();
+ cdoCompany.cdoWriteLock().lock();
if (mustReceiveNotifications)
{
- listener2.waitFor(1);
- assertEquals(1, listener2.getLockEvents().size());
+ controlViewListener.waitFor(1);
+ assertEquals(1, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = listener2.getLockEvents().get(0);
+ CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(0);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
assertEquals(1, lockStates.length);
- assertLockedObject(cdoCompany1, lockStates[0].getLockedObject());
+ assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
assertLockOwner(tx1, lockStates[0].getWriteLockOwner());
+ assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
}
- cdoCompany1.cdoWriteLock().unlock();
+ cdoCompany.cdoWriteLock().unlock();
if (mustReceiveNotifications)
{
- listener2.waitFor(2);
+ controlViewListener.waitFor(2);
- assertEquals(2, listener2.getLockEvents().size());
+ assertEquals(2, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = listener2.getLockEvents().get(1);
+ CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(1);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
assertEquals(1, lockStates.length);
- assertLockedObject(cdoCompany1, lockStates[0].getLockedObject());
+ assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
assertNull(lockStates[0].getWriteLockOwner());
+ assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
}
/* Test read lock */
- cdoCompany1.cdoReadLock().lock();
+ cdoCompany.cdoReadLock().lock();
if (mustReceiveNotifications)
{
- listener2.waitFor(3);
- assertEquals(3, listener2.getLockEvents().size());
+ controlViewListener.waitFor(3);
+ assertEquals(3, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = listener2.getLockEvents().get(2);
+ CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(2);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
assertEquals(1, lockStates.length);
- assertLockedObject(cdoCompany1, lockStates[0].getLockedObject());
+ assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
assertEquals(1, lockStates[0].getReadLockOwners().size());
CDOLockOwner tx1Lo = CDOLockUtil.createLockOwner(tx1);
assertEquals(true, lockStates[0].getReadLockOwners().contains(tx1Lo));
+ assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
}
- cdoCompany1.cdoReadLock().unlock();
+ cdoCompany.cdoReadLock().unlock();
if (mustReceiveNotifications)
{
- listener2.waitFor(4);
+ controlViewListener.waitFor(4);
- assertEquals(4, listener2.getLockEvents().size());
+ assertEquals(4, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = listener2.getLockEvents().get(3);
+ CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(3);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
assertEquals(1, lockStates.length);
assertEquals(0, lockStates[0].getReadLockOwners().size());
+ assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
}
/* Test write option */
- cdoCompany1.cdoWriteOption().lock();
+ cdoCompany.cdoWriteOption().lock();
if (mustReceiveNotifications)
{
- listener2.waitFor(5);
- assertEquals(5, listener2.getLockEvents().size());
+ controlViewListener.waitFor(5);
+ assertEquals(5, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = listener2.getLockEvents().get(4);
+ CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(4);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
assertEquals(1, lockStates.length);
- assertLockedObject(cdoCompany1, lockStates[0].getLockedObject());
+ assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
assertLockOwner(tx1, lockStates[0].getWriteOptionOwner());
+ assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
}
- cdoCompany1.cdoWriteOption().unlock();
+ cdoCompany.cdoWriteOption().unlock();
if (mustReceiveNotifications)
{
- listener2.waitFor(6);
+ controlViewListener.waitFor(6);
- assertEquals(6, listener2.getLockEvents().size());
+ assertEquals(6, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = listener2.getLockEvents().get(5);
+ CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(5);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
assertEquals(1, lockStates.length);
- assertLockedObject(cdoCompany1, lockStates[0].getLockedObject());
+ assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
assertNull(lockStates[0].getWriteOptionOwner());
+ assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
}
- assertEquals(0, listener1.getLockEvents().size());
+ assertEquals(0, transactionListener.getEvents().size());
if (!mustReceiveNotifications)
{
- assertEquals(0, listener2.getLockEvents().size());
+ assertEquals(0, controlViewListener.getEvents().size());
}
}
@@ -230,50 +237,6 @@ public class LockingNotificationsTest extends AbstractLockingTest
assertEquals(lo, lockOwner);
}
- /**
- * @author Caspar De Groot
- */
- private final class LockEventListener implements IListener
- {
- private List<CDOLocksChangedEvent> lockEvents = new LinkedList<CDOLocksChangedEvent>();
-
- public synchronized void notifyEvent(IEvent event)
- {
- if (event instanceof CDOLocksChangedEvent)
- {
- lockEvents.add((CDOLocksChangedEvent)event);
- notify();
- }
- }
-
- public List<CDOLocksChangedEvent> getLockEvents()
- {
- return lockEvents;
- }
-
- public synchronized void waitFor(int n)
- {
- long timeout = 2000;
- long t = 0;
- while (lockEvents.size() < n)
- {
- if (timeout <= 0)
- {
- fail("Timed out");
- }
- try
- {
- t = System.currentTimeMillis();
- wait(timeout);
- }
- catch (InterruptedException ex)
- {
- }
- timeout -= System.currentTimeMillis() - t;
- }
- }
- }
-
public void testEnableDisableNotifications() throws CommitException
{
CDOSession session1 = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
index 250fa7c..7983d39 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
@@ -15,8 +15,10 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractSyncingTest;
import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.util.TestListener2;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOLocksChangedEvent;
import org.eclipse.emf.cdo.view.CDOView;
/**
@@ -26,11 +28,7 @@ public class OfflineLockingTest extends AbstractSyncingTest
{
public void testLockAndUnlockThrough() throws Exception
{
- // InternalRepository clone = getRepository();
- // InternalRepository master = getRepository(clone.getName() + "_master");
-
CDOSession masterSession = openSession(getRepository().getName() + "_master");
- // CDOTransaction masterTx = masterSession.openTransaction();
CDOSession cloneSession = openSession();
waitForOnline(cloneSession.getRepositoryInfo());
@@ -42,18 +40,20 @@ public class OfflineLockingTest extends AbstractSyncingTest
Company company = getModel1Factory().createCompany();
res.getContents().add(company);
cloneTx.commit();
-
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
- cdoCompany.cdoWriteLock().lock();
CDOView masterView = masterSession.openView();
+ masterView.options().setLockNotificationEnabled(true);
+ TestListener2 masterViewListener = new TestListener2(CDOLocksChangedEvent.class);
+ masterView.addListener(masterViewListener);
CDOObject cdoCompanyOnMaster = masterView.getObject(cdoCompany.cdoID());
- assertEquals(true, cdoCompanyOnMaster.cdoWriteLock().isLockedByOthers());
- // int viewID = cloneTx.getViewID();
- // master.getLockManager().hasLock(LockType.WRITE, context, objectToLock);
+ cdoCompany.cdoWriteLock().lock();
+ masterViewListener.waitFor(1);
+ assertEquals(true, cdoCompanyOnMaster.cdoWriteLock().isLockedByOthers());
cdoCompany.cdoWriteLock().unlock();
+ masterViewListener.waitFor(2);
assertEquals(false, cdoCompanyOnMaster.cdoWriteLock().isLockedByOthers());
cloneSession.close();
@@ -62,6 +62,5 @@ public class OfflineLockingTest extends AbstractSyncingTest
public void testMasterLocks_ArrivalInClone() throws Exception
{
-
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java
new file mode 100644
index 0000000..b05050d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java
@@ -0,0 +1,75 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.util;
+
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.event.IEvent;
+import org.eclipse.net4j.util.event.IListener;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+/**
+ * @author Caspar De Groot
+ */
+public class TestListener2 implements IListener
+{
+ private List<IEvent> events = new LinkedList<IEvent>();
+
+ private Class<? extends IEvent> eventClass;
+
+ public TestListener2(Class<? extends IEvent> eventClass)
+ {
+ this.eventClass = eventClass;
+ }
+
+ public synchronized void notifyEvent(IEvent event)
+ {
+ if (eventClass.isAssignableFrom(event.getClass()))
+ {
+ events.add(event);
+ notify();
+ }
+ }
+
+ public List<IEvent> getEvents()
+ {
+ return events;
+ }
+
+ public synchronized void waitFor(int n)
+ {
+ long timeout = 2000;
+ long t = 0;
+
+ while (events.size() < n)
+ {
+ if (timeout <= 0)
+ {
+ Assert.fail("Timed out");
+ }
+
+ try
+ {
+ t = System.currentTimeMillis();
+ wait(timeout);
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+
+ timeout -= System.currentTimeMillis() - t;
+ }
+ }
+}
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 7e69345..ccf4144 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
@@ -948,6 +948,7 @@ public class CDOViewImpl extends AbstractCDOView
return;
}
+ updateLockStates(lockChangeInfo.getLockStates());
fireLocksChangedEvent(lockChangeInfo);
}