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/24 14:39:14 UTC
svn commit: r1038599 - in /jackrabbit/branches/2.1: ./
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
Author: jukka
Date: Wed Nov 24 13:39:13 2010
New Revision: 1038599
URL: http://svn.apache.org/viewvc?rev=1038599&view=rev
Log:
2.1: Merged revisions 1036117 and 1038201 (JCR-2813)
Modified:
jackrabbit/branches/2.1/ (props changed)
jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
Propchange: jackrabbit/branches/2.1/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Nov 24 13:39:13 2010
@@ -2,4 +2,4 @@
/jackrabbit/sandbox/JCR-1456:774917-886178
/jackrabbit/sandbox/JCR-2170:812417-816332
/jackrabbit/sandbox/tripod-JCR-2209:795441-795863
-/jackrabbit/trunk:931121,931479,931483-931484,931504,931609,931613,931838,931919,932318-932319,933144,933197,933203,933213,933216,933554,933646,933694,934405,934412,934849,935557,936668,938099,945528,950440,950680,955222,955229,955307,955852,961487,961626,964362,965539,986682,986686,986715,991144,995411-995412,996810,999298-999299,999965,1000947,1001707,1002065-1002066,1002084,1002101-1002102,1002168,1002170,1002589,1002608,1002657,1002729,1003423,1003470,1003542,1003773,1004182,1004184,1004223-1004224,1004652,1005057,1005112,1036336-1036337
+/jackrabbit/trunk:931121,931479,931483-931484,931504,931609,931613,931838,931919,932318-932319,933144,933197,933203,933213,933216,933554,933646,933694,934405,934412,934849,935557,936668,938099,945528,950440,950680,955222,955229,955307,955852,961487,961626,964362,965539,986682,986686,986715,991144,995411-995412,996810,999298-999299,999965,1000947,1001707,1002065-1002066,1002084,1002101-1002102,1002168,1002170,1002589,1002608,1002657,1002729,1003423,1003470,1003542,1003773,1004182,1004184,1004223-1004224,1004652,1005057,1005112,1036117,1036336-1036337,1038201
Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java?rev=1038599&r1=1038598&r2=1038599&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java Wed Nov 24 13:39:13 2010
@@ -163,17 +163,19 @@ public class LocalItemStateManager
return state;
}
- // check cache
- state = cache.retrieve(id);
- if (state == null) {
- // regular behaviour
- if (id.denotesNode()) {
- state = getNodeState((NodeId) id);
- } else {
- state = getPropertyState((PropertyId) id);
+ // check cache. synchronized to ensure an entry is not created twice.
+ synchronized (this) {
+ state = cache.retrieve(id);
+ if (state == null) {
+ // regular behaviour
+ if (id.denotesNode()) {
+ state = getNodeState((NodeId) id);
+ } else {
+ state = getPropertyState((PropertyId) id);
+ }
}
+ return state;
}
- return state;
}
/**
Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=1038599&r1=1038598&r2=1038599&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Wed Nov 24 13:39:13 2010
@@ -18,6 +18,8 @@ package org.apache.jackrabbit.core.state
import java.io.PrintStream;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -1692,20 +1694,64 @@ public class SharedItemStateManager
}
/**
+ * Identifiers of the item states that are currently being loaded from
+ * the underlying persistence manager. Used exclusively by the
+ * {@link #getNonVirtualItemState(ItemId)} method to prevent two threads
+ * from concurrently loading the same items.
+ */
+ private final Set<ItemId> currentlyLoading = new HashSet<ItemId>();
+
+ /**
* Returns the item state for the given id without considering virtual
* item state providers.
*/
private ItemState getNonVirtualItemState(ItemId id)
throws NoSuchItemStateException, ItemStateException {
+ // First check if the item state is already in the cache
ItemState state = cache.retrieve(id);
- if (state == null) {
- // not found in cache, load from persistent storage
+ if (state != null) {
+ return state;
+ }
+
+ // Wait if another thread is already loading this item state
+ synchronized (this) {
+ while (currentlyLoading.contains(id)) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ throw new ItemStateException(
+ "Interrupted while waiting for " + id, e);
+ }
+ }
+
+ state = cache.retrieve(id);
+ if (state != null) {
+ return state;
+ }
+
+ // No other thread has loaded the item state, so we'll do it
+ currentlyLoading.add(id);
+ }
+
+ try {
+ // Load the item state from persistent storage
+ // NOTE: This needs to happen outside a synchronized block!
state = loadItemState(id);
state.setStatus(ItemState.STATUS_EXISTING);
state.setContainer(this);
+
+ // put it in cache
cache.cache(state);
+
+ return state;
+ } finally {
+ // Notify other concurrent threads that we're done with this item
+ // NOTE: This needs to happen within the finally block!
+ synchronized (this) {
+ currentlyLoading.remove(id);
+ notifyAll();
+ }
}
- return state;
}
/**