Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2016-09-10 08:29:47 +0000
committerEike Stepper2016-09-10 08:29:47 +0000
commit52636ecc9b96f02a3a8338871a70643d78653951 (patch)
treeba748cd21fa972315e6255998504f609d41c8e98
parent1949a7c63791ce27888aac4c46cbe93147905227 (diff)
downloadcdo-52636ecc9b96f02a3a8338871a70643d78653951.tar.gz
cdo-52636ecc9b96f02a3a8338871a70643d78653951.tar.xz
cdo-52636ecc9b96f02a3a8338871a70643d78653951.zip
[469301] Have abillity to lock a set of locally detached objects atomically
https://bugs.eclipse.org/bugs/show_bug.cgi?id=469301
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java71
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java19
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java8
4 files changed, 97 insertions, 7 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java
index e000f22f42..1918e6dd97 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java
@@ -11,18 +11,27 @@
package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
+import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
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.CDOView;
+import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
+import org.eclipse.emf.spi.cdo.InternalCDOObject;
+import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+
import java.util.List;
/**
@@ -42,10 +51,14 @@ public class Bugzilla_469301_Test extends AbstractCDOTest
resource.getContents().add(company1);
transaction.commit();
- resource.getContents().remove(company0);
- resource.getContents().remove(company1);
+ TestListener2 controlListener1 = openControlView(transaction, session, "LOCAL");
+ TestListener2 controlListener2 = openControlView(transaction, openSession(), "REMOTE");
+ // Detach
List<? extends CDOObject> companies = CDOUtil.getCDOObjects(company0, company1);
+ resource.getContents().removeAll(companies);
+
+ // Lock
transaction.lockObjects(companies, LockType.WRITE, DEFAULT_TIMEOUT);
CDOLockState[] lockStates = transaction.getLockStatesOfObjects(companies);
@@ -58,5 +71,59 @@ public class Bugzilla_469301_Test extends AbstractCDOTest
LockState<Object, IView> serverLockState = serverLockState(session, lockState);
assertEquals(serverTransaction(transaction), serverLockState.getWriteLockOwner());
}
+
+ assertEvent(controlListener1, transaction, CDOLockChangeInfo.Operation.LOCK);
+ assertEvent(controlListener2, transaction, CDOLockChangeInfo.Operation.LOCK);
+
+ // Unlock
+ transaction.unlockObjects(companies, LockType.WRITE);
+
+ lockStates = transaction.getLockStatesOfObjects(companies);
+ assertEquals(2, lockStates.length);
+
+ for (CDOLockState lockState : lockStates)
+ {
+ assertNull(lockState.getWriteLockOwner());
+ assertNull(serverLockState(session, lockState));
+ }
+
+ assertEvent(controlListener1, transaction, CDOLockChangeInfo.Operation.UNLOCK);
+ assertEvent(controlListener2, transaction, CDOLockChangeInfo.Operation.UNLOCK);
+ }
+
+ private TestListener2 openControlView(CDOTransaction transaction, CDOSession session, String name)
+ {
+ CDOView controlView = session.openView();
+ controlView.options().setLockNotificationEnabled(true);
+
+ int counter = 1;
+ for (InternalCDOObject object : ((InternalCDOTransaction)transaction).getObjectsList())
+ {
+ // Load control object and make sure that it is not garbage collected.
+ InternalCDOObject controlObject = controlView.getObject(object);
+ controlView.properties().put(name + counter++, controlObject);
+ }
+
+ TestListener2 controlListener = new TestListener2(CDOViewLocksChangedEvent.class, name);
+ controlView.addListener(controlListener);
+ return controlListener;
+ }
+
+ private void assertEvent(TestListener2 controlListener, CDOLockOwner lockOwner, CDOLockChangeInfo.Operation operation)
+ {
+ controlListener.waitFor(1, DEFAULT_TIMEOUT);
+
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlListener.getEvents().get(0);
+ assertEquals(operation, event.getOperation());
+ assertEquals(LockType.WRITE, event.getLockType());
+ assertEquals(lockOwner, event.getLockOwner());
+ assertEquals(2, event.getLockStates().length);
+
+ for (CDOLockState lockState : event.getLockStates())
+ {
+ assertEquals(event.getOperation() == Operation.LOCK ? lockOwner : null, lockState.getWriteLockOwner());
+ }
+
+ controlListener.clearEvents();
}
}
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
index a871b5058a..69c6416889 100644
--- 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
@@ -16,6 +16,7 @@ import org.eclipse.net4j.util.event.IListener;
import org.junit.Assert;
+import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -166,10 +167,18 @@ public class TestListener2 implements IListener
waitFor(i, timeout);
}
+ public void clearEvents()
+ {
+ synchronized (this)
+ {
+ events.clear();
+ }
+ }
+
public String formatEvents(String prefix, String suffix)
{
StringBuilder builder = new StringBuilder();
-
+
synchronized (this)
{
for (Entry<IEvent, Long> entry : events.entrySet())
@@ -177,10 +186,16 @@ public class TestListener2 implements IListener
builder.append(prefix + entry.getValue() + ": " + entry.getKey() + suffix);
}
}
-
+
return builder.toString();
}
+ public void dump(PrintStream out)
+ {
+ out.println(this);
+ out.print(formatEvents(" ", "\n"));
+ }
+
@Override
public String toString()
{
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java
index 11a8184b85..ee091e349e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java
@@ -1271,10 +1271,10 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
List<CDOID> ids = new ArrayList<CDOID>();
for (CDOObject object : objects)
{
- InternalCDORevision revision = getRevision(object);
- if (revision != null)
+ CDOID id = getID((InternalCDOObject)object, true);
+ if (id != null)
{
- ids.add(revision.getID());
+ ids.add(id);
}
}
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 3e76bdc971..6322ba8f9e 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
@@ -657,6 +657,14 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv
}
}
}
+ else if (FSMUtil.isTransient(object))
+ {
+ CDOID id = getID((InternalCDOObject)object, true);
+ if (id != null)
+ {
+ objectIDs.add(id);
+ }
+ }
else
{
objectIDs.add(object.cdoID());

Back to the top