### Eclipse Workspace Patch 1.0 #P jackrabbit-core Index: src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (revision 899561) +++ src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (working copy) @@ -70,6 +70,7 @@ import java.io.OutputStreamWriter; import java.io.PrintStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; /** @@ -93,43 +94,66 @@ */ 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 @@ 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 @@ * Release lock on the lock map. */ private void release() { - lockMapLock.release(); + if (TransactionContext.getCurrentXid() == null) { + lockMapLock.release(); + } else { + xidlockMapLock.release(); + } }