You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2013/08/28 16:52:05 UTC

svn commit: r1518226 - /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java

Author: mduerig
Date: Wed Aug 28 14:52:05 2013
New Revision: 1518226

URL: http://svn.apache.org/r1518226
Log:
OAK-959: Deadlock between ChangeDispatcher and SegmentNodeStoreService
Use explicit lock in ChangeDispatcher instead of object monitor. Try to acquire lock for getting external changes and do nothing if this fails to avoid dead locking with incoming changes.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java?rev=1518226&r1=1518225&r2=1518226&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java Wed Aug 28 14:52:05 2013
@@ -24,6 +24,8 @@ import static org.apache.jackrabbit.oak.
 
 import java.util.Queue;
 import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -52,6 +54,7 @@ import org.apache.jackrabbit.oak.spi.sta
 public class ChangeDispatcher {
     private final NodeStore store;
     private final Set<Listener> listeners = Sets.newHashSet();
+    private final Lock changeLock = new ReentrantLock();
 
     private NodeState previousRoot;
 
@@ -91,10 +94,15 @@ public class ChangeDispatcher {
         return listener;
     }
 
-    private synchronized void contentChanged(@Nonnull NodeState before, @Nonnull NodeState after,
+    private void contentChanged(@Nonnull NodeState before, @Nonnull NodeState after,
             ContentSession contentSession) {
-        externalChange(checkNotNull(before));
-        internalChange(checkNotNull(after), contentSession);
+        changeLock.lock();
+        try {
+            externalChange(checkNotNull(before));
+            internalChange(checkNotNull(after), contentSession);
+        } finally {
+            changeLock.unlock();
+        }
     }
 
     private void externalChange(NodeState root) {
@@ -109,8 +117,14 @@ public class ChangeDispatcher {
         previousRoot = root;
     }
 
-    private synchronized void externalChange() {
-        externalChange(store.getRoot());
+    private void externalChange() {
+        if (changeLock.tryLock()) {
+            try {
+                externalChange(store.getRoot());
+            } finally {
+                changeLock.unlock();
+            }
+        }
     }
 
     private void register(Listener listener) {