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/11/18 09:03:54 UTC
svn commit: r1036336 - in
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core:
TransactionContext.java state/DefaultISMLocking.java state/ISMLocking.java
Author: jukka
Date: Thu Nov 18 08:03:53 2010
New Revision: 1036336
URL: http://svn.apache.org/viewvc?rev=1036336&view=rev
Log:
JCR-2753: Deadlock in DefaultISMLocking
Move the thread identifier computations to TransactionContext from where they can be better reused.
Note that it's not necessarily possible to "upgrade" an ISMLocking read lock.
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ISMLocking.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java?rev=1036336&r1=1036335&r2=1036336&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransactionContext.java Thu Nov 18 08:03:53 2010
@@ -23,6 +23,7 @@ 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;
@@ -338,4 +339,36 @@ public class TransactionContext extends
public static Xid getCurrentXid() {
return CURRENT_XID.get();
}
+
+ /**
+ * Returns the current thread identifier. The identifier is either the
+ * current thread instance or the global transaction identifier when
+ * running under a transaction.
+ *
+ * @return current thread identifier
+ */
+ public static Object getCurrentThreadId() {
+ Xid xid = TransactionContext.getCurrentXid();
+ if (xid != null) {
+ return xid.getGlobalTransactionId();
+ } else {
+ return Thread.currentThread();
+ }
+ }
+
+ /**
+ * Compares the given thread identifiers for equality.
+ *
+ * @see #getCurrentThreadId()
+ */
+ public static boolean isSameThreadId(Object a, Object b) {
+ if (a == b) {
+ return true;
+ } else if (a instanceof byte[] && b instanceof byte[]) {
+ return Arrays.equals((byte[]) a, (byte[]) b);
+ } else {
+ return false;
+ }
+ }
+
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java?rev=1036336&r1=1036335&r2=1036336&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java Thu Nov 18 08:03:53 2010
@@ -16,11 +16,9 @@
*/
package org.apache.jackrabbit.core.state;
-import java.util.Arrays;
+import static org.apache.jackrabbit.core.TransactionContext.getCurrentThreadId;
+import static org.apache.jackrabbit.core.TransactionContext.isSameThreadId;
-import javax.transaction.xa.Xid;
-
-import org.apache.jackrabbit.core.TransactionContext;
import org.apache.jackrabbit.core.id.ItemId;
/**
@@ -87,8 +85,9 @@ public class DefaultISMLocking implement
*/
public synchronized ReadLock acquireReadLock(ItemId id)
throws InterruptedException {
+ Object currentId = getCurrentThreadId();
while (writerId != null
- ? (writerCount > 0 && !isSameId(writerId, getCurrentId()))
+ ? (writerCount > 0 && !isSameThreadId(writerId, currentId))
: writersWaiting > 0) {
wait();
}
@@ -116,12 +115,12 @@ public class DefaultISMLocking implement
*/
public synchronized WriteLock acquireWriteLock(ChangeLog changeLog)
throws InterruptedException {
- Object currentId = getCurrentId();
+ Object currentId = getCurrentThreadId();
writersWaiting++;
try {
while (writerId != null
- ? !isSameId(writerId, currentId) : readerCount > 0) {
+ ? !isSameThreadId(writerId, currentId) : readerCount > 0) {
wait();
}
} finally {
@@ -153,33 +152,4 @@ public class DefaultISMLocking implement
}
}
- /**
- * Returns the current thread identifier. The identifier is either the
- * current thread instance or the global transaction identifier when
- * running under a transaction.
- *
- * @return current thread identifier
- */
- private Object getCurrentId() {
- Xid xid = TransactionContext.getCurrentXid();
- if (xid != null) {
- return xid.getGlobalTransactionId();
- } else {
- return Thread.currentThread();
- }
- }
-
- /**
- * Compares the given thread identifiers for equality.
- */
- private boolean isSameId(Object a, Object b) {
- if (a == b) {
- return true;
- } else if (a instanceof byte[] && b instanceof byte[]) {
- return Arrays.equals((byte[]) a, (byte[]) b);
- } else {
- return false;
- }
- }
-
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ISMLocking.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ISMLocking.java?rev=1036336&r1=1036335&r2=1036336&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ISMLocking.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ISMLocking.java Thu Nov 18 08:03:53 2010
@@ -42,7 +42,9 @@ import org.apache.jackrabbit.core.id.Ite
* <li>While a write lock is held for a change log <code>C</code>, the holder
* of the write lock (and any related threads) needs to be able to acquire
* a read lock even if other writers are waiting for the lock. This behaviour
- * must continue also when the write lock has been downgraded.</li>
+ * must continue also when the write lock has been downgraded. Note that it
+ * is not necessary for a holder of a read lock to be able to upgrade to a
+ * write lock.</li>
* </ul>
*/
public interface ISMLocking {