You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/04/27 16:14:30 UTC

svn commit: r938462 - in /jackrabbit/branches/1.6: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/

Author: jukka
Date: Tue Apr 27 14:14:30 2010
New Revision: 938462

URL: http://svn.apache.org/viewvc?rev=938462&view=rev
Log:
1.6: Merged revisions 923277, 923597 and 925982 (JCR-2554)

Modified:
    jackrabbit/branches/1.6/   (props changed)
    jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java
    jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
    jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java

Propchange: jackrabbit/branches/1.6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr 27 14:14:30 2010
@@ -1,4 +1,4 @@
 /jackrabbit/branches/1.5:794012,794100,794102
 /jackrabbit/branches/1.x:801262-801983,812129,812371
 /jackrabbit/branches/2.0:899183,900703
-/jackrabbit/trunk:770143-773197,773483,773525-773555,773584,773588,773828,773835-775756,775833,775836,775840,775868,775981,775986,776036,776256,776310,776313,776321-776322,776332,776356-776357,776362,776373,776650-776693,776737,776757,776776-776777,777024,777029,777034,777478,777509,777541,777548,777936,778445,778613,778616,778621,778645,778720,778802,779032,779040,779068-779071,779074,779076,779081,779084,779086-779088,779090-779092,779094-779096,779101,779223,779225,779227-779228,779230,779233-779234,779460,779475-779476,779504,779550,779552,779555,779561,779563,779583,779590,779618,779621-779622,779624,779642,779654,779657-779659,779661,779936,780006,780010,780025,780085,780985,780989,780993,781017,781051,781054,781294-781300,781305-781311,781318,781328,781338,781344,781347,781369,781372,781377,781416-781417,781423,782621-782622,782644,782646,782652,782669,782675,782677,782683,782694,782921,782925,782930,782936,783002,783004-783005,783042-783043,783239,783243,783245,78327
 8,783304,783319-783321,783324,783326-783327,783330-783333,783337-783338,783340-783341,783343,783345-783347,783356,783359,783383,783386,783412,783435,783444,783447,783523,783688,783703,783708,783710,783719,783757,783759,783761,783786,783809,784011,784013,784039,784058,784060-784061,784090-784091,784106,784108-784109,784111,784117-784120,784124,784163,784261,784680,784691,784696,784760,784824,785112,785116,785157,785169,785209,785492,785517,785519,785529,785533,785535,785539-785540,785545,785580,785589-785590,785592,785594,785597,785602,785627,785629,785631,785635,785645,785668,785711,785725,785777,785863,785981,786003,786019,786028,786062,786075,786089-786090,786093-786094,786144,786146-786147,786149,786167,786280,786295,786319,786329-786330,786336,786409,786419,786423,786480,786485,786492,786513,786562,786565,786680,786685,787183,787219,787241,787942,787952,787964,787996,788002,788012-788013,788350-788351,788443,788446,788450,789245,789257,789269-789270,789279,789307,789312,
 789324,789338,789347,789485,789629,789809,789986,790054,790056,790065-790066,790068,790070-790071,790118,790127,790153,790235-790236,790528,790537,790541,790557-790558,790568,790590,790600,790603,790629,790814,790826,790834,790887,790892,790901,790930,790939,791180,791253,791255,791438-791439,791441,791452,791457,791475,791492,791505,791520,791527,791737,791832,791884,791906,792102,792109,792118,792138,792152,792155-792156,792160,792162,792167-792168,792175,792180-792181,792211,792214,792218,792437,792453,792464,792467,792469,792485,792488,792496,792498,792508-792509,792547-792548,792588-792589,792849,792894-792895,792912,792932,792934,792968,793012-793013,793015-793016,793018,793046-793047,793072,793180,793238,793240,793243,793283,793484-793485,793507,793559,793571,793830,793836,793840,794162,794190,794193,794253,794278,794293-794294,794302,794304,794323,794329,794600,794617,794633,794641,794644,794652,794674,794702,794718,794743,794783,794994,795046,795049,795082,795096,79
 5136,795138,795841-795842,795854,795866,796584,796586,796757,796845,796855,796876,796899,796955,796957,797094,797139,797158,797386,797399,797410,797414,797416-797417,797424,797470,797484,797488-797489,797539,797549,797634,797662,797836,798141,798183,798196,798209,798306,798834,798844,798847-798848,798889-798890,798940,798958,799188,799284,799550,799595,799599,799610,800269,800464,800466,800478,800483,800715,800807,800829,800854,800862-800863,801104,801125-801126,801128,801135,801169,801210,801213,801226,801241,801968,801973,802691,802754,812102,812369,815233,816124,818482,819491,820925,825772,829015,830575,830665,881283,889133,892253,899181,900702,927393,933646,935557
+/jackrabbit/trunk:770143-773197,773483,773525-773555,773584,773588,773828,773835-775756,775833,775836,775840,775868,775981,775986,776036,776256,776310,776313,776321-776322,776332,776356-776357,776362,776373,776650-776693,776737,776757,776776-776777,777024,777029,777034,777478,777509,777541,777548,777936,778445,778613,778616,778621,778645,778720,778802,779032,779040,779068-779071,779074,779076,779081,779084,779086-779088,779090-779092,779094-779096,779101,779223,779225,779227-779228,779230,779233-779234,779460,779475-779476,779504,779550,779552,779555,779561,779563,779583,779590,779618,779621-779622,779624,779642,779654,779657-779659,779661,779936,780006,780010,780025,780085,780985,780989,780993,781017,781051,781054,781294-781300,781305-781311,781318,781328,781338,781344,781347,781369,781372,781377,781416-781417,781423,782621-782622,782644,782646,782652,782669,782675,782677,782683,782694,782921,782925,782930,782936,783002,783004-783005,783042-783043,783239,783243,783245,78327
 8,783304,783319-783321,783324,783326-783327,783330-783333,783337-783338,783340-783341,783343,783345-783347,783356,783359,783383,783386,783412,783435,783444,783447,783523,783688,783703,783708,783710,783719,783757,783759,783761,783786,783809,784011,784013,784039,784058,784060-784061,784090-784091,784106,784108-784109,784111,784117-784120,784124,784163,784261,784680,784691,784696,784760,784824,785112,785116,785157,785169,785209,785492,785517,785519,785529,785533,785535,785539-785540,785545,785580,785589-785590,785592,785594,785597,785602,785627,785629,785631,785635,785645,785668,785711,785725,785777,785863,785981,786003,786019,786028,786062,786075,786089-786090,786093-786094,786144,786146-786147,786149,786167,786280,786295,786319,786329-786330,786336,786409,786419,786423,786480,786485,786492,786513,786562,786565,786680,786685,787183,787219,787241,787942,787952,787964,787996,788002,788012-788013,788350-788351,788443,788446,788450,789245,789257,789269-789270,789279,789307,789312,
 789324,789338,789347,789485,789629,789809,789986,790054,790056,790065-790066,790068,790070-790071,790118,790127,790153,790235-790236,790528,790537,790541,790557-790558,790568,790590,790600,790603,790629,790814,790826,790834,790887,790892,790901,790930,790939,791180,791253,791255,791438-791439,791441,791452,791457,791475,791492,791505,791520,791527,791737,791832,791884,791906,792102,792109,792118,792138,792152,792155-792156,792160,792162,792167-792168,792175,792180-792181,792211,792214,792218,792437,792453,792464,792467,792469,792485,792488,792496,792498,792508-792509,792547-792548,792588-792589,792849,792894-792895,792912,792932,792934,792968,793012-793013,793015-793016,793018,793046-793047,793072,793180,793238,793240,793243,793283,793484-793485,793507,793559,793571,793830,793836,793840,794162,794190,794193,794253,794278,794293-794294,794302,794304,794323,794329,794600,794617,794633,794641,794644,794652,794674,794702,794718,794743,794783,794994,795046,795049,795082,795096,79
 5136,795138,795841-795842,795854,795866,796584,796586,796757,796845,796855,796876,796899,796955,796957,797094,797139,797158,797386,797399,797410,797414,797416-797417,797424,797470,797484,797488-797489,797539,797549,797634,797662,797836,798141,798183,798196,798209,798306,798834,798844,798847-798848,798889-798890,798940,798958,799188,799284,799550,799595,799599,799610,800269,800464,800466,800478,800483,800715,800807,800829,800854,800862-800863,801104,801125-801126,801128,801135,801169,801210,801213,801226,801241,801968,801973,802691,802754,812102,812369,815233,816124,818482,819491,820925,825772,829015,830575,830665,881283,889133,892253,899181,900702,923277,923597,925982,927393,933646,935557

Modified: jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java?rev=938462&r1=938461&r2=938462&view=diff
==============================================================================
--- jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java (original)
+++ jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java Tue Apr 27 14:14:30 2010
@@ -23,7 +23,6 @@ import org.apache.jackrabbit.util.Timer;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.Xid;
 
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -339,17 +338,5 @@ public class TransactionContext extends 
     public static Xid getCurrentXid() {
         return (Xid) CURRENT_XID.get();
     }
-    
-    /**
-     * Helper Method to check if the given {@link Xid} has the same globalTransactionId
-     * as the current {@link Xid} bind to the {@link #CURRENT_XID} ThreadLocal
-     * @param xid Xid to check
-     * @param fallback if either the given {@link Xid} or the current {@link Xid} is null we can not check if they 
-     *        are same, the fallback value will be returned
-     * @return true if the same otherwise false
-     */
-    public static boolean isCurrentXid(Xid xid, boolean fallback) {
-        Xid currentXid = (Xid) CURRENT_XID.get();
-        return fallback ? true : (currentXid == null || xid == null) ? fallback : Arrays.equals(xid.getGlobalTransactionId(), currentXid.getGlobalTransactionId());  
-    }
+
 }

Modified: jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=938462&r1=938461&r2=938462&view=diff
==============================================================================
--- jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Tue Apr 27 14:14:30 2010
@@ -70,6 +70,7 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
 
 /**
@@ -93,43 +94,66 @@ public class LockManagerImpl implements 
      */
     private final PathMap lockMap = new PathMap();
 
-    private final ReentrantLock lockMapLock = new ReentrantLock(){
-        
+    /**
+     * Thread aware lock to path map.
+     */
+    private final ReentrantLock lockMapLock = new ReentrantLock();
+    
+    /**
+     * Xid aware lock to path map.
+     */
+    private final ReentrantLock xidlockMapLock = new ReentrantLock(){
+
+    	/**
+    	 * The actice Xid of this {@link ReentrantLock}
+    	 */
         private Xid activeXid;
+
+        /**
+         * Check if the given Xid comes from the same globalTX
+         * @param otherXid
+         * @return true if same globalTX otherwise false
+         */
+        boolean isSameGlobalTx(Xid otherXid) {
+    	    return (activeXid == otherXid) || Arrays.equals(activeXid.getGlobalTransactionId(), otherXid.getGlobalTransactionId());
+    	}
         
+        /**
+         * {@inheritDoc}
+         */
         public void acquire() throws InterruptedException {
-            if (Thread.interrupted()) throw new InterruptedException();
-            Thread caller = Thread.currentThread();
+        	if (Thread.interrupted()) throw new InterruptedException();
+        	Xid currentXid = TransactionContext.getCurrentXid();
             synchronized(this) {
-                boolean allow = TransactionContext.isCurrentXid(activeXid, caller == owner_);
-                if (allow) {
-                    ++holds_;
-                } else {
-                    try {  
-                        while (owner_ != null) 
-                            wait(); 
-                        owner_ = caller;
-                        activeXid = (Xid) TransactionContext.getCurrentXid();
-                        holds_ = 1;
-                    } catch (InterruptedException ex) {
-                        notify();
-                        throw ex;
-                    }
-                }
+            	if (currentXid == activeXid || (activeXid != null && isSameGlobalTx(currentXid))) { 
+                ++holds_;
+            	} else {
+            		try {  
+            			while (activeXid != null) 
+            				wait(); 
+            			activeXid = currentXid;
+            			holds_ = 1;
+            		} catch (InterruptedException ex) {
+            			notify();
+            			throw ex;
+            		}
+            	}
             }
         }
         
+        /**
+         * {@inheritDoc}
+         */
         public synchronized void release()  {
-            boolean allow = TransactionContext.isCurrentXid(activeXid, Thread.currentThread() == owner_);
-            if (!allow)
+        	Xid currentXid = TransactionContext.getCurrentXid();
+            if (activeXid != null && !isSameGlobalTx(currentXid))
                 throw new Error("Illegal Lock usage"); 
 
-            if (--holds_ == 0) {
-                owner_ = null;
+              if (--holds_ == 0) {
                 activeXid = null;
                 notify(); 
-            }
-        }       
+              }
+        }
     };
 
     /**
@@ -735,7 +759,11 @@ public class LockManagerImpl implements 
     private void acquire() {
         for (;;) {
             try {
-                lockMapLock.acquire();
+            	if (TransactionContext.getCurrentXid() == null) {
+            		lockMapLock.acquire();
+            	} else {
+            		xidlockMapLock.acquire();
+            	}
                 break;
             } catch (InterruptedException e) {
                 // ignore
@@ -747,7 +775,11 @@ public class LockManagerImpl implements 
      * Release lock on the lock map.
      */
     private void release() {
-        lockMapLock.release();
+    	if (TransactionContext.getCurrentXid() == null) {
+    		lockMapLock.release();
+    	} else {
+    		xidlockMapLock.release();
+    	}
     }
 
     /**

Modified: jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java?rev=938462&r1=938461&r2=938462&view=diff
==============================================================================
--- jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java (original)
+++ jackrabbit/branches/1.6/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java Tue Apr 27 14:14:30 2010
@@ -20,11 +20,10 @@ import java.util.Arrays;
 
 import javax.transaction.xa.Xid;
 
-import org.apache.jackrabbit.core.ItemId;
 import org.apache.jackrabbit.core.TransactionContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.core.ItemId;
 
+import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
 import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
 import EDU.oswego.cs.dl.util.concurrent.Sync;
 
@@ -36,54 +35,65 @@ import EDU.oswego.cs.dl.util.concurrent.
 public class DefaultISMLocking implements ISMLocking {
 
     /**
-     * Logger instance
+     * The internal read-write lock.
+	 * Thread concerning ReentrantWriterPreferenceReadWriteLock
      */
-    private static final Logger log = LoggerFactory.getLogger(DefaultISMLocking.class);
-
+    private final ReadWriteLock rwLock = new ReentrantWriterPreferenceReadWriteLock();
+    
     /**
-     * The internal read-write lock.
+     * The internal Xid aware read-write lock.
      */
-    private final RWLock rwLock = new RWLock();
-
+    private final ReadWriteLock xidRwLock = new XidRWLock();
+    
     /**
      * {@inheritDoc}
      */
-    public ReadLock acquireReadLock(ItemId id)
-            throws InterruptedException {
-        return new ReadLockImpl(rwLock.readLock());
+    public ReadLock acquireReadLock(ItemId id) throws InterruptedException {
+    	if (TransactionContext.getCurrentXid() == null) {
+            return new ReadLockImpl(rwLock.readLock());
+    	} else {
+            return new ReadLockImpl(xidRwLock.readLock());
+    	}
     }
 
     /**
      * {@inheritDoc}
      */
-    public WriteLock acquireWriteLock(ChangeLog changeLog)
-            throws InterruptedException {
-        return new WriteLock() {
-
-            {
-                rwLock.writeLock().acquire();
-                rwLock.setActiveXid(TransactionContext.getCurrentXid());
-            }
-
-            /**
-             * {@inheritDoc}
-             */
-            public void release() {
-                rwLock.writeLock().release();
-            }
-
-            /**
-             * {@inheritDoc}
-             */
-            public ReadLock downgrade() throws InterruptedException {
-                ReadLock rLock = new ReadLockImpl(rwLock.readLock());
-                release();
-                return rLock;
-            }
-        };
+    public WriteLock acquireWriteLock(ChangeLog changeLog) throws InterruptedException {
+    	if (TransactionContext.getCurrentXid() == null) {
+    		return new WriteLockImpl(rwLock);
+    	} else {
+    		return new WriteLockImpl(xidRwLock);
+    	}
     }
 
-    private static final class ReadLockImpl implements ReadLock {
+    private static final class WriteLockImpl implements WriteLock {
+    	
+    	private ReadWriteLock readWriteLock;
+    	
+    	private WriteLockImpl(ReadWriteLock readWriteLock) throws InterruptedException {
+    		this.readWriteLock = readWriteLock;
+    		this.readWriteLock.writeLock().acquire();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void release() {
+		    this.readWriteLock.writeLock().release();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public ReadLock downgrade() throws InterruptedException {
+		    ReadLock rLock = new ReadLockImpl(this.readWriteLock.readLock());
+		    release();
+		    return rLock;
+		}
+	}
+
+	private static final class ReadLockImpl implements ReadLock {
 
         private final Sync readLock;
 
@@ -100,45 +110,61 @@ public class DefaultISMLocking implement
         }
     }
 
-    private static final class RWLock extends ReentrantWriterPreferenceReadWriteLock {
+	/**
+	 * Xid concerning ReentrantWriterPreferenceReadWriteLock
+	 */
+    private static final class XidRWLock extends ReentrantWriterPreferenceReadWriteLock {
 
         private Xid activeXid;
 
         /**
-         * Allow reader when there is no active writer, or current thread owns
+         * Check if the given Xid comes from the same globalTX
+         * @param otherXid
+         * @return true if same globalTX otherwise false
+         */
+        boolean isSameGlobalTx(Xid otherXid) {
+    	    return (activeXid == otherXid) || Arrays.equals(activeXid.getGlobalTransactionId(), otherXid.getGlobalTransactionId());
+    	}
+
+        /**
+         * Allow reader when there is no active Xid, or current Xid owns
          * the write lock (reentrant).
          */
         protected boolean allowReader() {
-            return TransactionContext.isCurrentXid(activeXid, (activeWriter_ == null || activeWriter_ == Thread.currentThread()));
+        	Xid currentXid = TransactionContext.getCurrentXid();
+        	return (activeXid == null && waitingWriters_ == 0) || isSameGlobalTx(currentXid);
         }
 
         /**
-         * Sets the active Xid
-         * @param xid
-         */
-        synchronized void setActiveXid(Xid xid) {
-            if (activeXid != null && xid != null) {
-                boolean sameGTI = Arrays.equals(activeXid.getGlobalTransactionId(), xid.getGlobalTransactionId());
-                if (!sameGTI) {
-                    log.warn("Unable to set the ActiveXid while a other one is associated with a different GloalTransactionId with this RWLock.");
-                    return;
-                }
+         * {@inheritDoc}
+         */  
+        protected synchronized boolean startWrite() {
+        	Xid currentXid = TransactionContext.getCurrentXid();
+            if (activeXid != null && isSameGlobalTx(currentXid)) { // already held; re-acquire
+            	++writeHolds_;
+                return true;
+            } else if (writeHolds_ == 0) {
+            	if (activeReaders_ == 0 || (readers_.size() == 1 && readers_.get(currentXid) != null)) {
+            		activeXid = currentXid;
+            		writeHolds_ = 1;
+            		return true;
+            	} else {
+            		return false;
+            	}
+            } else {
+            	return false;
             }
-            activeXid = xid;
         }
 
         /**
          * {@inheritDoc}
-         * 
-         * If there are no more writeHolds the activeXid will be set to null
          */
         protected synchronized Signaller endWrite() {
             --writeHolds_;
             if (writeHolds_ > 0) {  // still being held
-                return null;
+            	return null;
             } else {
-                activeXid = null;
-                activeWriter_ = null;
+            	activeXid = null;
                 if (waitingReaders_ > 0 && allowReader()) {
                     return readerLock_;
                 } else if (waitingWriters_ > 0) {
@@ -148,5 +174,52 @@ public class DefaultISMLocking implement
                 }
             }
         }
+
+        /**
+         * {@inheritDoc}
+         */
+		protected synchronized boolean startRead() {
+			Xid currentXid = TransactionContext.getCurrentXid();
+		    Object c = readers_.get(currentXid);
+		    if (c != null) { // already held -- just increment hold count
+		    	readers_.put(currentXid, new Integer(((Integer)(c)).intValue()+1));
+		    	++activeReaders_;
+		    	return true;
+		    } else if (allowReader()) {
+		    	readers_.put(currentXid, IONE);
+		    	++activeReaders_;
+		    	return true;
+		    } else {
+		    	return false;
+		    }
+		}
+
+        /**
+         * {@inheritDoc}
+         */
+		protected synchronized Signaller endRead() {
+			Xid currentXid = TransactionContext.getCurrentXid();
+		    Object c = readers_.get(currentXid);
+		    if (c == null) {
+		    	throw new IllegalStateException();
+		    }
+		    --activeReaders_;
+		    if (c != IONE) { // more than one hold; decrement count
+		    	int h = ((Integer)(c)).intValue()-1;
+		    	Integer ih = (h == 1)? IONE : new Integer(h);
+		    	readers_.put(currentXid, ih);
+		    	return null;
+		    } else {
+		    	readers_.remove(currentXid);
+		    
+		    	if (writeHolds_ > 0) { // a write lock is still held
+		    		return null;
+		    	} else if (activeReaders_ == 0 && waitingWriters_ > 0) {
+		    		return writerLock_;
+		    	} else  {
+		    		return null;
+		    	}
+		    }
+		}
     }
 }