cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jo...@apache.org
Subject svn commit: r692265 - /cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
Date Thu, 04 Sep 2008 21:47:06 GMT
Author: joerg
Date: Thu Sep  4 14:47:05 2008
New Revision: 692265

URL: http://svn.apache.org/viewvc?rev=692265&view=rev
Log:
Fix ConcurrentModificationException (again) introduced with refactoring synchronization

Modified:
    cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java

Modified: cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java?rev=692265&r1=692264&r2=692265&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
(original)
+++ cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
Thu Sep  4 14:47:05 2008
@@ -67,7 +67,7 @@
  * this setting for web applications. Set "session-bound-continuations"
  * configuration option to true to activate this mode.</li>
  * </ul>
- * 
+ *
  * @since March 19, 2002
  * @see ContinuationsManager
  * @version $Id$
@@ -118,7 +118,7 @@
     }
 
     public void contextualize(Context context) throws ContextException {
-        this.context = context;        
+        this.context = context;
     }
 
     public void service(ServiceManager manager) throws ServiceException {
@@ -128,12 +128,12 @@
     public void configure(Configuration config) {
         this.defaultTimeToLive = config.getAttributeAsInteger("time-to-live", (3600 * 1000));
         this.bindContinuationsToSession = config.getAttributeAsBoolean( "session-bound-continuations",
false );
-        
+
         // create a global ContinuationsHolder if this the "session-bound-continuations"
parameter is set to false
         if (!this.bindContinuationsToSession) {
             this.continuationsHolder = new WebContinuationsHolder();
         }
-        
+
         // create a thread that invalidates the continuations
         final Configuration expireConf = config.getChild("expirations-check");
         final long initialDelay = expireConf.getChild("offset", true).getValueAsLong(180000);
@@ -156,7 +156,7 @@
     public WebContinuation createWebContinuation(Object kont,
                                                  WebContinuation parent,
                                                  int timeToLive,
-                                                 String interpreterId, 
+                                                 String interpreterId,
                                                  ContinuationsDisposer disposer) {
         int ttl = timeToLive == 0 ? defaultTimeToLive : timeToLive;
 
@@ -181,17 +181,17 @@
         if (continuationsHolder == null) {
             return null;
         }
-        
+
         WebContinuation kont = continuationsHolder.get(id);
         if (kont == null) {
-            return null;            
+            return null;
         }
-        
+
         if (kont.hasExpired()) {
             removeContinuation(continuationsHolder, kont);
             return null;
         }
-            
+
         if (!kont.interpreterMatches(interpreterId)) {
             getLogger().error("WK: Continuation (" + kont.getId()
                               + ") lookup for wrong interpreter. Bound to: "
@@ -385,17 +385,21 @@
      * continuationsHolder.
      */
     protected void invalidateContinuations(WebContinuationsHolder continuationsHolder) {
+        // It's not possible to just iterate over continuationsHolder.holder since _invalidate(..)
+        // calls remove(..) on the map leading to ConcurrentModification at the end.
+        WebContinuation[] continuations;
         synchronized (continuationsHolder.holder) {
-            for (Iterator iter = continuationsHolder.holder.values().iterator(); iter.hasNext();)
{
-                WebContinuation wk = (WebContinuation) iter.next();
-                _detach(wk);
-                _invalidate(continuationsHolder, wk);
-            }
+            continuations = new WebContinuation[continuationsHolder.holder.size()];
+            continuations = (WebContinuation[]) continuationsHolder.holder.values().toArray(continuations);
+        }
+        for (int i = 0; i < continuations.length; i++) {
+            _detach(continuations[i]);
+            _invalidate(continuationsHolder, continuations[i]);
         }
     }
 
     /**
-     * Lookup a proper web continuations holder. 
+     * Lookup a proper web continuations holder.
      * @param createNew
      *            should the manager create a continuations holder in session
      *            when none found?
@@ -404,7 +408,7 @@
         //there is only one holder if continuations are not bound to session
         if (!this.bindContinuationsToSession)
             return this.continuationsHolder;
-        
+
         //if continuations bound to session lookup a proper holder in the session
         Map objectModel = ContextHelper.getObjectModel(this.context);
         Request request = ObjectModelHelper.getRequest(objectModel);
@@ -413,7 +417,7 @@
             return null;
 
         HttpSession session = request.getSession(true);
-        WebContinuationsHolder holder = 
+        WebContinuationsHolder holder =
             (WebContinuationsHolder) session.getAttribute(
                     WebContinuationsHolder.CONTINUATIONS_HOLDER);
         if (!createNew)
@@ -439,7 +443,7 @@
                 rootWebContinuations.add(webContinuation);
             }
         }
-        
+
         Set clonedRootWebContinuations = new HashSet();
         for (Iterator iter = rootWebContinuations.iterator(); iter.hasNext();) {
             WebContinuation rootContinuation = (WebContinuation) iter.next();
@@ -450,7 +454,7 @@
 
     /**
      * Get a list of all web continuations (data only)
-     * 
+     *
      * @deprecated
      */
     public List getWebContinuationsDataBeanList() {
@@ -471,7 +475,7 @@
      */
     protected void displayExpireSet() {
         StringBuffer wkSet = new StringBuffer("\nWK; Expire set size: ");
-        
+
         synchronized (this.expirations) {
             wkSet.append(this.expirations.size());
             for (Iterator i = this.expirations.iterator(); i.hasNext();) {
@@ -491,7 +495,7 @@
     /**
      * Dump to Log file all <code>WebContinuation</code>s
      * in the system.
-     * 
+     *
      * This method will be changed to be an internal method solely for debugging
      * purposes just like {@link #displayExpireSet()}.
      */
@@ -508,11 +512,11 @@
     /**
      * A holder for WebContinuations. When bound to session notifies the
      * continuations manager of session invalidation.
-     * 
+     *
      * For thread-safe access you have to synchronize on the Map {@link #holder}!
      */
     protected class WebContinuationsHolder implements HttpSessionBindingListener {
-        
+
         private final static String CONTINUATIONS_HOLDER = "o.a.c.c.f.SCMI.WebContinuationsHolder";
 
         private Map holder = Collections.synchronizedMap(new HashMap());
@@ -529,14 +533,10 @@
             this.holder.remove(wk.getId());
         }
 
-        public Set getContinuationIds() {
-            return holder.keySet();
-        }
-        
         public boolean contains(String continuationId) {
             return this.holder.containsKey(continuationId);
         }
-        
+
         public boolean contains(WebContinuation wk) {
             return contains(wk.getId());
         }



Mime
View raw message