### Eclipse Workspace Patch 1.0 #P jackrabbit-core Index: src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java (revision 1241895) +++ src/main/java/org/apache/jackrabbit/core/version/VersioningLock.java (working copy) @@ -16,12 +16,8 @@ */ package org.apache.jackrabbit.core.version; -import java.util.Arrays; - -import javax.transaction.xa.Xid; - -import org.apache.jackrabbit.core.TransactionContext; - +import static org.apache.jackrabbit.core.TransactionContext.getCurrentThreadId; +import static org.apache.jackrabbit.core.TransactionContext.isSameThreadId; 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,30 +32,15 @@ /** * The internal read-write lock. - * Thread concerning ReentrantWriterPreferenceReadWriteLock */ - private final ReadWriteLock rwLock = - new ReentrantWriterPreferenceReadWriteLock(); + private final ReadWriteLock rwLock = new XAAwareRWLock(); - /** - * The internal Xid aware read-write lock. - */ - private final ReadWriteLock xidRwLock = new XidRWLock(); - public ReadLock acquireReadLock() throws InterruptedException { - if (TransactionContext.getCurrentXid() == null) { - return new ReadLock(rwLock.readLock()); - } else { - return new ReadLock(xidRwLock.readLock()); - } + return new ReadLock(rwLock.readLock()); } public WriteLock acquireWriteLock() throws InterruptedException { - if (TransactionContext.getCurrentXid() == null) { - return new WriteLock(rwLock); - } else { - return new WriteLock(xidRwLock); - } + return new WriteLock(rwLock); } public static class WriteLock { @@ -100,64 +81,51 @@ } /** - * Xid concerning ReentrantWriterPreferenceReadWriteLock + * XA concerning ReentrantWriterPreferenceReadWriteLock */ - private static final class XidRWLock + private static final class XAAwareRWLock extends ReentrantWriterPreferenceReadWriteLock { - private Xid activeXid; + private Object activeWriter; /** - * Check if the given Xid comes from the same globalTX - * @param otherXid - * @return true if same globalTX otherwise false + * {@inheritDoc} */ - 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). - */ - @Override protected boolean allowReader() { - Xid currentXid = TransactionContext.getCurrentXid(); - return (activeXid == null && waitingWriters_ == 0) || isSameGlobalTx(currentXid); + Object currentId = getCurrentThreadId(); + return (activeWriter == null && waitingWriters_ == 0) || isSameThreadId(activeWriter, currentId); } /** * {@inheritDoc} */ - @Override protected synchronized boolean startWrite() { - Xid currentXid = TransactionContext.getCurrentXid(); - if (activeXid != null && isSameGlobalTx(currentXid)) { // already held; re-acquire - ++writeHolds_; + Object currentId = getCurrentThreadId(); + if (activeWriter != null && isSameThreadId(activeWriter, currentId)) { // 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; - } + if (activeReaders_ == 0 || (readers_.size() == 1 && readers_.get(currentId) != null)) { + activeWriter = currentId; + writeHolds_ = 1; + return true; + } else { + return false; + } } else { - return false; + return false; } } /** * {@inheritDoc} */ - @Override protected synchronized Signaller endWrite() { --writeHolds_; if (writeHolds_ > 0) { // still being held - return null; + return null; } else { - activeXid = null; + activeWriter = null; if (waitingReaders_ > 0 && allowReader()) { return readerLock_; } else if (waitingWriters_ > 0) { @@ -171,54 +139,50 @@ /** * {@inheritDoc} */ - @Override - @SuppressWarnings("unchecked") - 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, (Integer) (c) + 1); - ++activeReaders_; - return true; - } else if (allowReader()) { - readers_.put(currentXid, IONE); - ++activeReaders_; - return true; - } else { - return false; - } - } + @SuppressWarnings("unchecked") + protected synchronized boolean startRead() { + Object currentId = getCurrentThreadId(); + Object c = readers_.get(currentId); + if (c != null) { // already held -- just increment hold count + readers_.put(currentId, new Integer(((Integer)(c)).intValue()+1)); + ++activeReaders_; + return true; + } else if (allowReader()) { + readers_.put(currentId, IONE); + ++activeReaders_; + return true; + } else { + return false; + } + } /** * {@inheritDoc} */ - @Override - @SuppressWarnings("unchecked") - 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) -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; - } - } - } - + @SuppressWarnings("unchecked") + protected synchronized Signaller endRead() { + Object currentId = getCurrentThreadId(); + Object c = readers_.get(currentId); + 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(currentId, ih); + return null; + } else { + readers_.remove(currentId); + + if (writeHolds_ > 0) { // a write lock is still held + return null; + } else if (activeReaders_ == 0 && waitingWriters_ > 0) { + return writerLock_; + } else { + return null; + } + } + } } - } \ No newline at end of file