[573654] Commits with autoReleaseLocks==false trigger empty lock notification events, nevertheless
https://bugs.eclipse.org/bugs/show_bug.cgi?id=573654
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java
index e163a21..38920a8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java
@@ -19,6 +19,7 @@
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.session.CDOSessionLocksChangedEvent;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.model1.Category;
@@ -36,6 +37,7 @@
import org.eclipse.net4j.util.concurrent.RWOLockManager;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
+import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.io.IOUtil;
import java.util.ArrayList;
@@ -45,6 +47,7 @@
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.AssertionFailedError;
@@ -53,6 +56,37 @@
*/
public class LockingManagerTest extends AbstractLockingTest
{
+ public void testAutoReleaseLocks() throws Exception
+ {
+ CDOSession session = openSession();
+
+ AtomicInteger counter = new AtomicInteger();
+ try (AutoCloseable listener = EventUtil.addListener(session, CDOSessionLocksChangedEvent.class, event -> counter.incrementAndGet()))
+ {
+ CDOTransaction transaction = session.openTransaction();
+ transaction.options().setAutoReleaseLocksEnabled(false);
+
+ CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+ assertWriteLock(false, resource);
+
+ transaction.commit();
+ assertWriteLock(false, resource);
+
+ resource.cdoWriteLock().lock();
+ assertWriteLock(true, resource);
+
+ resource.getContents().add(getModel1Factory().createSupplier());
+ transaction.commit();
+ assertWriteLock(true, resource);
+
+ resource.cdoWriteLock().unlock();
+ assertWriteLock(false, resource);
+
+ sleep(200);
+ assertEquals(2, counter.get());
+ }
+ }
+
public void testUnlockAll() throws Exception
{
RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<>();
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 834ff02..3d8d3fa 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
@@ -2201,7 +2201,11 @@
if (success)
{
fireEvent(new SessionInvalidationEvent(sender, commitInfo, invalidationData.getSecurityImpact(), oldPermissionsFinal));
- fireEvent(new SessionLocksChangedEvent(sender, lockChangeInfo));
+
+ if (lockChangeInfo != null)
+ {
+ fireEvent(new SessionLocksChangedEvent(sender, lockChangeInfo));
+ }
commitInfoManager.notifyCommitInfoHandlers(commitInfo);
}
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 9f5eb8d..4026bcd 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
@@ -4972,9 +4972,15 @@
}
}
- lockStates.putAll(newLockStates);
+ lockStates.putAll(newLockStates); // Side effect!!!
- CDOLockState[] array = objectsToUnlock.toArray(new CDOLockState[objectsToUnlock.size()]);
+ int size = objectsToUnlock.size();
+ if (size == 0)
+ {
+ return null;
+ }
+
+ CDOLockState[] array = objectsToUnlock.toArray(new CDOLockState[size]);
return makeLockChangeInfo(CDOLockChangeInfo.Operation.UNLOCK, null, result.getTimeStamp(), array);
}
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 4597fc0..dc069e2 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
@@ -585,7 +585,7 @@
@Override
public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
{
- CDOLockChangeInfo event = null;
+ CDOLockChangeInfo lockChangeInfoToFire = null;
try
{
@@ -598,7 +598,7 @@
if (lockChangeInfo.isInvalidateAll())
{
lockStates.clear();
- event = lockChangeInfo;
+ lockChangeInfoToFire = lockChangeInfo;
return;
}
@@ -619,7 +619,7 @@
if (options().isLockNotificationEnabled())
{
- event = lockChangeInfo;
+ lockChangeInfoToFire = lockChangeInfo;
}
}
finally
@@ -630,9 +630,9 @@
}
finally
{
- if (event != null)
+ if (lockChangeInfoToFire != null)
{
- fireLocksChangedEvent(sender, event);
+ fireLocksChangedEvent(sender, lockChangeInfoToFire);
}
}
}