summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgidijus Vaishnora2011-03-01 02:38:01 (EST)
committerEgidijus Vaishnora2011-03-01 02:38:01 (EST)
commit91f07816579edec91cc7b0d4d6c197cdd2c0d1ce (patch)
tree6fb7d529e1a635323cc23613fa9bdae146c32a42
parent334a22268c9b9f09dc4db6292a17db47a9e7f590 (diff)
downloadcdo-91f07816579edec91cc7b0d4d6c197cdd2c0d1ce.zip
cdo-91f07816579edec91cc7b0d4d6c197cdd2c0d1ce.tar.gz
cdo-91f07816579edec91cc7b0d4d6c197cdd2c0d1ce.tar.bz2
[324585] StackOverflowError on delta notification
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_324585_Test.java16
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDONotificationBuilder.java20
2 files changed, 21 insertions, 15 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_324585_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_324585_Test.java
index 5d3f965..4f980b5 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_324585_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_324585_Test.java
@@ -19,16 +19,17 @@ import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
-import org.junit.Test;
-
/**
* @author Eike Stepper
*/
public class Bugzilla_324585_Test extends AbstractCDOTest
{
- @Test
+ /**
+ * To see the problem it may be necessary to limit the stack size with e.g. -Xss256k
+ */
public void testUpdate() throws CommitException
{
// user 1
@@ -51,11 +52,12 @@ public class Bugzilla_324585_Test extends AbstractCDOTest
category2.eAdapters().add(new AdapterImpl());
// user1
- for (int i = 0; i < 1000; i++)
+ EList<Product1> products = category1.getProducts();
+ for (int i = 0; i < 10000; i++)
{
- final Product1 product = getModel1Factory().createProduct1();
- product.setName("product" + i);
- category1.getProducts().add(product);
+ Product1 product = getModel1Factory().createProduct1();
+ product.setName("Product" + i);
+ products.add(product);
}
transaction1.commit();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDONotificationBuilder.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDONotificationBuilder.java
index 8ad0a4a..01d4668 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDONotificationBuilder.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDONotificationBuilder.java
@@ -27,6 +27,7 @@ import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.notify.impl.NotificationChainImpl;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.InternalEObject;
@@ -47,7 +48,7 @@ public class CDONotificationBuilder extends CDOFeatureDeltaVisitorImpl
private CDORevisionDelta revisionDelta;
- private CDODeltaNotificationImpl notification;
+ private NotificationChainImpl notification;
private Set<CDOObject> detachedObjects;
@@ -75,7 +76,7 @@ public class CDONotificationBuilder extends CDOFeatureDeltaVisitorImpl
public synchronized NotificationChain buildNotification(InternalEObject object, InternalCDORevision oldRevision,
CDORevisionDelta revisionDelta, Set<CDOObject> detachedObjects)
{
- notification = null;
+ notification = new NotificationChainImpl();
this.object = object;
this.revisionDelta = revisionDelta;
@@ -254,13 +255,16 @@ public class CDONotificationBuilder extends CDOFeatureDeltaVisitorImpl
protected void add(CDODeltaNotificationImpl newNotificaton)
{
newNotificaton.setRevisionDelta(revisionDelta);
- if (notification == null)
+ if (notification.add(newNotificaton))
{
- notification = newNotificaton;
- }
- else
- {
- notification.add(newNotificaton);
+ int size = notification.size();
+ if (size > 1)
+ {
+ CDODeltaNotificationImpl previousNotification = (CDODeltaNotificationImpl)notification.get(size - 2);
+
+ // Ensure that previousNotification.next is set
+ previousNotification.add(newNotificaton);
+ }
}
}