[jboss-cvs] JBossAS SVN: r112497 - projects/ejb3/branches/jboss-ejb3-core-1.3/src/main/java/org/jboss/ejb3/cache/simple.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Dec 1 04:10:18 EST 2011
Author: wolfc
Date: 2011-12-01 04:10:18 -0500 (Thu, 01 Dec 2011)
New Revision: 112497
Modified:
projects/ejb3/branches/jboss-ejb3-core-1.3/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java
Log:
JBPAPP-7523: make sure activation runs outside the lock
Modified: projects/ejb3/branches/jboss-ejb3-core-1.3/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java
===================================================================
--- projects/ejb3/branches/jboss-ejb3-core-1.3/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java 2011-12-01 09:09:54 UTC (rev 112496)
+++ projects/ejb3/branches/jboss-ejb3-core-1.3/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java 2011-12-01 09:10:18 UTC (rev 112497)
@@ -21,14 +21,17 @@
*/
package org.jboss.ejb3.cache.simple;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Queue;
-import java.util.Map.Entry;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
-
import javax.ejb.EJBException;
import javax.ejb.NoSuchEJBException;
@@ -68,6 +71,8 @@
private Queue<StatefulBeanContext> passivationQueue = new LinkedBlockingQueue<StatefulBeanContext>();
+ private Map<Object, FutureTask<StatefulBeanContext>> activations = new HashMap<Object, FutureTask<StatefulBeanContext>>();
+
protected class CacheMap extends LinkedHashMap<Object, StatefulBeanContext>
{
private static final long serialVersionUID = 4514182777643616159L;
@@ -430,7 +435,7 @@
return get(key, true);
}
- public StatefulBeanContext get(Object key, boolean markInUse) throws EJBException
+ public StatefulBeanContext get(final Object key, boolean markInUse) throws EJBException
{
StatefulBeanContext entry = null;
synchronized (cacheMap)
@@ -465,34 +470,69 @@
}
if (entry == null)
{
+ // JBPAPP-7523: create a task for activation while holding the pm lock,
+ // then execute said task outside the lock
+ FutureTask<StatefulBeanContext> activation;
+ final boolean executeActivation;
synchronized(pm)
{
- synchronized (cacheMap)
+ activation = activations.get(key);
+ if (activation == null)
{
- entry = cacheMap.get(key);
- }
- if(entry == null)
- {
- entry = pm.activateSession(key);
- if (entry == null)
+ activation = new FutureTask<StatefulBeanContext>(new Callable<StatefulBeanContext>()
{
- throw new NoSuchEJBException("Could not find stateful bean: " + key);
- }
- --passivatedCount;
-
- // We cache the entry even if we will throw an exception below
- // as we may still need it for its children and XPC references
- if (log.isTraceEnabled())
- {
- log.trace("Caching activated context " + entry.getId() + " of type " + entry.getClass());
- }
-
- synchronized (cacheMap)
- {
- cacheMap.put(key, entry);
- }
+ @Override
+ public StatefulBeanContext call() throws Exception {
+ StatefulBeanContext entry;
+ synchronized (cacheMap)
+ {
+ entry = cacheMap.get(key);
+ }
+ if(entry == null)
+ {
+ entry = pm.activateSession(key);
+ if (entry == null)
+ {
+ throw new NoSuchEJBException("Could not find stateful bean: " + key);
+ }
+ --passivatedCount;
+
+ // We cache the entry even if we will throw an exception below
+ // as we may still need it for its children and XPC references
+ if (log.isTraceEnabled())
+ {
+ log.trace("Caching activated context " + entry.getId() + " of type " + entry.getClass());
+ }
+
+ synchronized (cacheMap)
+ {
+ cacheMap.put(key, entry);
+ }
+ }
+ return entry;
+ }
+ });
+ activations.put(key, activation);
+ executeActivation = true;
}
+ else
+ executeActivation = false;
}
+ if (executeActivation)
+ activation.run();
+ try {
+ entry = activation.get();
+ }
+ catch (InterruptedException e)
+ {
+ throw new EJBException(e);
+ }
+ catch (ExecutionException e)
+ {
+ if (e.getCause() instanceof RuntimeException)
+ throw (RuntimeException) e.getCause();
+ throw (EJBException) new EJBException().initCause(e.getCause());
+ }
}
// Now we know entry isn't null
More information about the jboss-cvs-commits
mailing list