You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2011/02/07 11:54:48 UTC

svn commit: r1067910 - in /jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: cluster/ClusterNode.java journal/AbstractJournal.java version/InternalVersionManagerBase.java version/VersioningLock.java

Author: dpfister
Date: Mon Feb  7 10:54:48 2011
New Revision: 1067910

URL: http://svn.apache.org/viewvc?rev=1067910&view=rev
Log:
JCR-2881 - Deadlock on version operations in a clustered environment

Modified:
    jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java
    jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AbstractJournal.java
    jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java
    jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java

Modified: jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java?rev=1067910&r1=1067909&r2=1067910&view=diff
==============================================================================
--- jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java (original)
+++ jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java Mon Feb  7 10:54:48 2011
@@ -27,6 +27,7 @@ import javax.jcr.RepositoryException;
 import org.apache.jackrabbit.core.cluster.WorkspaceRecord.CreateWorkspaceAction;
 import org.apache.jackrabbit.core.config.ClusterConfig;
 import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.jackrabbit.core.journal.AbstractJournal;
 import org.apache.jackrabbit.core.journal.InstanceRevision;
 import org.apache.jackrabbit.core.journal.Journal;
 import org.apache.jackrabbit.core.journal.JournalException;
@@ -36,6 +37,7 @@ import org.apache.jackrabbit.core.journa
 import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
 import org.apache.jackrabbit.core.observation.EventState;
 import org.apache.jackrabbit.core.state.ChangeLog;
+import org.apache.jackrabbit.core.version.InternalVersionManagerImpl;
 import org.apache.jackrabbit.core.xml.ClonedInputSource;
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;
 import org.slf4j.Logger;
@@ -636,6 +638,11 @@ public class ClusterNode implements Runn
         public void setListener(UpdateEventListener listener) {
             if (workspace == null) {
                 versionUpdateListener = listener;
+                if (journal instanceof AbstractJournal &&
+                        versionUpdateListener instanceof InternalVersionManagerImpl) {
+                    ((AbstractJournal) journal).setInternalVersionManager(
+                            (InternalVersionManagerImpl) versionUpdateListener);
+                }
             } else {
                 wspUpdateListeners.remove(workspace);
                 if (listener != null) {

Modified: jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AbstractJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AbstractJournal.java?rev=1067910&r1=1067909&r2=1067910&view=diff
==============================================================================
--- jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AbstractJournal.java (original)
+++ jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AbstractJournal.java Mon Feb  7 10:54:48 2011
@@ -21,6 +21,8 @@ import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.jackrabbit.core.version.InternalVersionManagerImpl;
+import org.apache.jackrabbit.core.version.VersioningLock;
 import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
@@ -86,6 +88,11 @@ public abstract class AbstractJournal im
     private File repHome;
 
     /**
+     * Internal version manager.
+     */
+    private InternalVersionManagerImpl internalVersionManager;
+
+    /**
      * {@inheritDoc}
      */
     public void init(String id, NamespaceResolver resolver) throws JournalException {
@@ -176,6 +183,20 @@ public abstract class AbstractJournal im
      * {@inheritDoc}
      */
     public void sync() throws JournalException {
+        if (internalVersionManager != null) {
+            VersioningLock.ReadLock lock =
+                internalVersionManager.acquireReadLock();
+            try {
+                internalSync();
+            } finally {
+                lock.release();
+            }
+        } else {
+            internalSync();
+        }
+    }
+
+    private void internalSync() throws JournalException {
         try {
             rwLock.readLock().acquire();
         } catch (InterruptedException e) {
@@ -237,6 +258,20 @@ public abstract class AbstractJournal im
      * @throws JournalException if an error occurs
      */
     public void lockAndSync() throws JournalException {
+        if (internalVersionManager != null) {
+            VersioningLock.ReadLock lock =
+                internalVersionManager.acquireReadLock();
+            try {
+                internalLockAndSync();
+            } finally {
+                lock.release();
+            }
+        } else {
+            internalLockAndSync();
+        }
+    }
+
+    private void internalLockAndSync() throws JournalException {
         try {
             rwLock.writeLock().acquire();
         } catch (InterruptedException e) {
@@ -354,6 +389,13 @@ public abstract class AbstractJournal im
     }
 
     /**
+     * Set the version manager.
+     */
+    public void setInternalVersionManager(InternalVersionManagerImpl internalVersionManager) {
+        this.internalVersionManager = internalVersionManager;
+    }
+
+    /**
      * Return the repository home.
      *
      * @return the repository home

Modified: jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java?rev=1067910&r1=1067909&r2=1067910&view=diff
==============================================================================
--- jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java (original)
+++ jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java Mon Feb  7 10:54:48 2011
@@ -187,7 +187,7 @@ abstract class InternalVersionManagerBas
      * acquires the read lock on this version manager.
      * @return returns the read lock
      */
-    protected VersioningLock.ReadLock acquireReadLock() {
+    public VersioningLock.ReadLock acquireReadLock() {
         while (true) {
             try {
                 return rwLock.acquireReadLock();

Modified: jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java?rev=1067910&r1=1067909&r2=1067910&view=diff
==============================================================================
--- jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java (original)
+++ jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java Mon Feb  7 10:54:48 2011
@@ -32,7 +32,7 @@ import EDU.oswego.cs.dl.util.concurrent.
  * to be re-entered not just by a thread that's already holding the lock but
  * by any thread within the same transaction.
  */
-class VersioningLock {
+public class VersioningLock {
 
     /**
      * The internal read-write lock.
@@ -127,7 +127,7 @@ class VersioningLock {
 
         /**
          * {@inheritDoc}
-         */  
+         */
         protected synchronized boolean startWrite() {
             Xid currentXid = TransactionContext.getCurrentXid();
             if (activeXid != null && isSameGlobalTx(currentXid)) { // already held; re-acquire