jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r411154 - in /jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core: NodeImpl.java version/AbstractVersionManager.java version/InternalVersionImpl.java version/VersionManagerImpl.java version/XAVersionManager.java
Date Fri, 02 Jun 2006 13:24:32 GMT
Author: tripod
Date: Fri Jun  2 06:24:31 2006
New Revision: 411154

URL: http://svn.apache.org/viewvc?rev=411154&view=rev
Log:
JCR-449 inconsistency in internal version items during commits

Modified:
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=411154&r1=411153&r2=411154&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Fri
Jun  2 06:24:31 2006
@@ -3091,6 +3091,11 @@
         sanityCheck();
 
         checkVersionable();
+
+        // transactions workaround.
+        NodeId id = NodeId.valueOf(getProperty(QName.JCR_VERSIONHISTORY).getString());
+        session.getVersionManager().getVersionHistory(id);
+
         return (VersionHistory) getProperty(QName.JCR_VERSIONHISTORY).getNode();
     }
 
@@ -3103,6 +3108,11 @@
         sanityCheck();
 
         checkVersionable();
+
+        // transactions workaround.
+        NodeId id = NodeId.valueOf(getProperty(QName.JCR_BASEVERSION).getString());
+        session.getVersionManager().getVersion(id);
+
         return (Version) getProperty(QName.JCR_BASEVERSION).getNode();
     }
 

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java?rev=411154&r1=411153&r2=411154&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
(original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
Fri Jun  2 06:24:31 2006
@@ -16,8 +16,10 @@
  */
 package org.apache.jackrabbit.core.version;
 
-import org.apache.jackrabbit.core.NodeImpl;
+import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
 import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.LocalItemStateManager;
@@ -28,8 +30,8 @@
 import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
-import javax.jcr.Value;
 import javax.jcr.Session;
+import javax.jcr.Value;
 import javax.jcr.version.VersionException;
 import javax.jcr.version.VersionHistory;
 import java.util.List;
@@ -54,6 +56,23 @@
      */
     protected NodeStateEx historyRoot;
 
+    /**
+     * the lock on this version manager
+     */
+    private final ReadWriteLock rwLock =
+            new ReentrantWriterPreferenceReadWriteLock() {
+                /**
+                 * Allow reader when there is no active writer, or current
+                 * thread owns the write lock (reentrant).
+                 * <p/>
+                 * the 'noLockHack' is only temporary (hopefully)
+                 */
+                protected boolean allowReader() {
+                    return activeWriter_ == null
+                        || activeWriter_ == Thread.currentThread();
+                }
+            };
+
     //-------------------------------------------------------< VersionManager >
 
     /**
@@ -93,6 +112,48 @@
     //-------------------------------------------------------< implementation >
 
     /**
+     * aquires the write lock on this version manager.
+     */
+    protected void aquireWriteLock() {
+        while (true) {
+            try {
+                rwLock.writeLock().acquire();
+                return;
+            } catch (InterruptedException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * releases the write lock on this version manager.
+     */
+    protected void releaseWriteLock() {
+        rwLock.writeLock().release();
+    }
+
+    /**
+     * aquires the read lock on this version manager.
+     */
+    protected void aquireReadLock() {
+        while (true) {
+            try {
+                rwLock.readLock().acquire();
+                return;
+            } catch (InterruptedException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * releases the read lock on this version manager.
+     */
+    protected void releaseReadLock() {
+        rwLock.readLock().release();
+    }
+
+    /**
      * {@inheritDoc}
      */
     public VersionHistory getVersionHistory(Session session, NodeState node)
@@ -141,9 +202,11 @@
     InternalVersionHistory createVersionHistory(NodeState node)
             throws RepositoryException {
 
+        aquireWriteLock();
         try {
             stateMgr.edit();
         } catch (IllegalStateException e) {
+            releaseWriteLock();
             throw new RepositoryException("Unable to start edit operation", e);
         }
 
@@ -185,6 +248,7 @@
                 // update operation failed, cancel all modifications
                 stateMgr.cancel();
             }
+            releaseWriteLock();
         }
     }
 
@@ -227,40 +291,46 @@
     protected InternalVersion checkin(InternalVersionHistoryImpl history, NodeImpl node)
             throws RepositoryException {
 
-        // 1. search a predecessor, suitable for generating the new name
-        Value[] values = node.getProperty(QName.JCR_PREDECESSORS).getValues();
-        InternalVersion best = null;
-        for (int i = 0; i < values.length; i++) {
-            InternalVersion pred = history.getVersion(NodeId.valueOf(values[i].getString()));
-            if (best == null || pred.getSuccessors().length < best.getSuccessors().length)
{
-                best = pred;
+        aquireReadLock();
+        String versionName;
+        try {
+            // 1. search a predecessor, suitable for generating the new name
+            Value[] values = node.getProperty(QName.JCR_PREDECESSORS).getValues();
+            InternalVersion best = null;
+            for (int i = 0; i < values.length; i++) {
+                InternalVersion pred = history.getVersion(NodeId.valueOf(values[i].getString()));
+                if (best == null || pred.getSuccessors().length < best.getSuccessors().length)
{
+                    best = pred;
+                }
             }
-        }
 
-        // 2. generate version name (assume no namespaces in version names)
-        String versionName = best.getName().getLocalName();
-        int pos = versionName.lastIndexOf('.');
-        if (pos > 0) {
-            versionName = versionName.substring(0, pos + 1)
-                + (Integer.parseInt(versionName.substring(pos + 1)) + 1);
-        } else {
-            versionName = String.valueOf(best.getSuccessors().length + 1) + ".0";
-        }
-
-        // 3. check for colliding names
-        while (history.hasVersion(new QName("", versionName))) {
-            versionName += ".1";
-        }
+            // 2. generate version name (assume no namespaces in version names)
+            versionName = best.getName().getLocalName();
+            int pos = versionName.lastIndexOf('.');
+            if (pos > 0) {
+                versionName = versionName.substring(0, pos + 1)
+                    + (Integer.parseInt(versionName.substring(pos + 1)) + 1);
+            } else {
+                versionName = String.valueOf(best.getSuccessors().length + 1) + ".0";
+            }
+
+            // 3. check for colliding names
+            while (history.hasVersion(new QName("", versionName))) {
+                versionName += ".1";
+            }
 
-        try {
             stateMgr.edit();
         } catch (IllegalStateException e) {
+            releaseReadLock();
             throw new RepositoryException("Unable to start edit operation.");
         }
 
         boolean succeeded = false;
 
         try {
+            aquireWriteLock();
+            releaseReadLock();
+
             InternalVersionImpl v = history.checkin(new QName("", versionName), node);
             stateMgr.update();
             succeeded = true;
@@ -273,6 +343,7 @@
                 // update operation failed, cancel all modifications
                 stateMgr.cancel();
             }
+            releaseWriteLock();
         }
     }
 
@@ -289,9 +360,11 @@
     protected void removeVersion(InternalVersionHistoryImpl history, QName name)
             throws VersionException, RepositoryException {
 
+        aquireWriteLock();
         try {
             stateMgr.edit();
         } catch (IllegalStateException e) {
+            releaseWriteLock();
             throw new VersionException("Unable to start edit operation", e);
         }
         boolean succeeded = false;
@@ -306,6 +379,7 @@
                 // update operation failed, cancel all modifications
                 stateMgr.cancel();
             }
+            releaseWriteLock();
         }
     }
 
@@ -323,9 +397,11 @@
                                               boolean move)
             throws RepositoryException {
 
+        aquireWriteLock();
         try {
             stateMgr.edit();
         } catch (IllegalStateException e) {
+            releaseWriteLock();
             throw new VersionException("Unable to start edit operation", e);
         }
         InternalVersion v = null;
@@ -341,6 +417,7 @@
                 // update operation failed, cancel all modifications
                 stateMgr.cancel();
             }
+            releaseWriteLock();
         }
         return v;
     }

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java?rev=411154&r1=411153&r2=411154&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
Fri Jun  2 06:24:31 2006
@@ -135,16 +135,21 @@
      * {@inheritDoc}
      */
     public InternalVersion[] getSuccessors() {
-        InternalValue[] values = node.getPropertyValues(QName.JCR_SUCCESSORS);
-        if (values != null) {
-            InternalVersion[] versions = new InternalVersion[values.length];
-            for (int i = 0; i < values.length; i++) {
-                NodeId vId = new NodeId((UUID) values[i].internalValue());
-                versions[i] = versionHistory.getVersion(vId);
+        try {
+            vMgr.aquireReadLock();
+            InternalValue[] values = node.getPropertyValues(QName.JCR_SUCCESSORS);
+            if (values != null) {
+                InternalVersion[] versions = new InternalVersion[values.length];
+                for (int i = 0; i < values.length; i++) {
+                    NodeId vId = new NodeId((UUID) values[i].internalValue());
+                    versions[i] = versionHistory.getVersion(vId);
+                }
+                return versions;
+            } else {
+                return new InternalVersion[0];
             }
-            return versions;
-        } else {
-            return new InternalVersion[0];
+        } finally {
+            vMgr.releaseReadLock();
         }
     }
 

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java?rev=411154&r1=411153&r2=411154&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
Fri Jun  2 06:24:31 2006
@@ -228,33 +228,34 @@
             return null;
         }
         try {
-            synchronized (versionItems) {
-                InternalVersionItem item = (InternalVersionItem) versionItems.get(id);
-                if (item == null) {
-                    if (stateMgr.hasItemState(id)) {
-                        NodeState state = (NodeState) stateMgr.getItemState(id);
-                        NodeStateEx pNode = new NodeStateEx(stateMgr, ntReg, state, null);
-                        NodeId parentId = pNode.getParentId();
-                        InternalVersionItem parent = getItem(parentId);
-                        QName ntName = state.getNodeTypeName();
-                        if (ntName.equals(QName.NT_FROZENNODE)) {
-                            item = new InternalFrozenNodeImpl(this, pNode, parent);
-                        } else if (ntName.equals(QName.NT_VERSIONEDCHILD)) {
-                            item = new InternalFrozenVHImpl(this, pNode, parent);
-                        } else if (ntName.equals(QName.NT_VERSION)) {
-                            item = ((InternalVersionHistory) parent).getVersion(id);
-                        } else if (ntName.equals(QName.NT_VERSIONHISTORY)) {
-                            item = new InternalVersionHistoryImpl(this, pNode);
-                        } else {
-                            return null;
-                        }
+            aquireReadLock();
+            InternalVersionItem item = (InternalVersionItem) versionItems.get(id);
+            if (item == null) {
+                if (stateMgr.hasItemState(id)) {
+                    NodeState state = (NodeState) stateMgr.getItemState(id);
+                    NodeStateEx pNode = new NodeStateEx(stateMgr, ntReg, state, null);
+                    NodeId parentId = pNode.getParentId();
+                    InternalVersionItem parent = getItem(parentId);
+                    QName ntName = state.getNodeTypeName();
+                    if (ntName.equals(QName.NT_FROZENNODE)) {
+                        item = new InternalFrozenNodeImpl(this, pNode, parent);
+                    } else if (ntName.equals(QName.NT_VERSIONEDCHILD)) {
+                        item = new InternalFrozenVHImpl(this, pNode, parent);
+                    } else if (ntName.equals(QName.NT_VERSION)) {
+                        item = ((InternalVersionHistory) parent).getVersion(id);
+                    } else if (ntName.equals(QName.NT_VERSIONHISTORY)) {
+                        item = new InternalVersionHistoryImpl(this, pNode);
+                    } else {
+                        return null;
                     }
-                    versionItems.put(id, item);
                 }
-                return item;
+                versionItems.put(id, item);
             }
+            return item;
         } catch (ItemStateException e) {
             throw new RepositoryException(e);
+        } finally {
+            releaseReadLock();
         }
     }
 
@@ -350,7 +351,8 @@
      * @param item item updated
      */
     private void itemUpdated(InternalVersionItem item) {
-        synchronized (versionItems) {
+        try {
+            aquireReadLock();
             InternalVersionItem cached = (InternalVersionItem) versionItems.remove(item.getId());
             if (cached != null) {
                 if (cached instanceof InternalVersionHistoryImpl) {
@@ -363,6 +365,8 @@
                     }
                 }
             }
+        } finally {
+            releaseReadLock();
         }
     }
 

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java?rev=411154&r1=411153&r2=411154&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
(original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
Fri Jun  2 06:24:31 2006
@@ -449,11 +449,13 @@
      * global repository manager to update its caches.
      */
     public void commit(TransactionContext tx) throws TransactionException {
+        vMgr.aquireWriteLock();
         ((XAItemStateManager) stateMgr).commit(tx);
         vMgr.getSharedStateMgr().setNoLockHack(false);
 
         Map xaItems = (Map) tx.getAttribute(ITEMS_ATTRIBUTE_NAME);
         vMgr.itemsUpdated(xaItems.values());
+        vMgr.releaseWriteLock();
     }
 
     /**



Mime
View raw message