tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject svn commit: r694274 - /tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
Date Thu, 11 Sep 2008 14:25:11 GMT
Author: hlship
Date: Thu Sep 11 07:25:11 2008
New Revision: 694274

URL: http://svn.apache.org/viewvc?rev=694274&view=rev
Log:
TAPESTRY-2561: Rapidly refreshing a page, even the same page, can cause a deadlock related
to class loading
				

Modified:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java?rev=694274&r1=694273&r2=694274&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
(original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
Thu Sep 11 07:25:11 2008
@@ -44,6 +44,9 @@
 
     private final Logger logger;
 
+    /**
+     * Lazily instantiated.  Access is guarded by BARRIER.
+     */
     private Object moduleBuilder;
 
     // Set to true when invoking the module constructor. Used to
@@ -52,11 +55,15 @@
     private boolean insideConstructor;
 
     /**
-     * Keyed on fully qualified service id; values are instantiated services (proxies).
+     * Keyed on fully qualified service id; values are instantiated services (proxies). Guarded
by BARRIER.
      */
     private final Map<String, Object> services = CollectionFactory.newCaseInsensitiveMap();
 
-    private final ConcurrentBarrier barrier = new ConcurrentBarrier();
+    /**
+     * The barrier is shared by all modules, which means that creation of *any* service for
any module is single
+     * threaded.
+     */
+    private final static ConcurrentBarrier BARRIER = new ConcurrentBarrier();
 
     public ModuleImpl(InternalRegistry registry, ServiceActivityTracker tracker, ModuleDef
moduleDef,
                       ClassFactory classFactory, Logger logger)
@@ -148,9 +155,20 @@
         {
             public Object invoke()
             {
-                Object result = create(def, eagerLoadProxies);
+                // In a race condition, two threads may try to create the same service simulatenously.
+                // The second will block until after the first creates the service.
+
+                Object result = services.get(key);
 
-                services.put(key, result);
+                // Normally, result is null, unless some other thread slipped in and created
the service
+                // proxy.
+
+                if (result == null)
+                {
+                    result = create(def, eagerLoadProxies);
+
+                    services.put(key, result);
+                }
 
                 return result;
             }
@@ -164,14 +182,14 @@
 
                 if (result == null)
                 {
-                    result = barrier.withWrite(create);
+                    result = BARRIER.withWrite(create);
                 }
 
                 return result;
             }
         };
 
-        return barrier.withRead(find);
+        return BARRIER.withRead(find);
     }
 
     public void collectEagerLoadServices(Collection<EagerLoadServiceProxy> proxies)
@@ -261,7 +279,7 @@
     {
         public Object invoke()
         {
-            if (moduleBuilder == null) barrier.withWrite(instantiateModuleBuilder);
+            if (moduleBuilder == null) BARRIER.withWrite(instantiateModuleBuilder);
 
             return moduleBuilder;
         }
@@ -269,7 +287,7 @@
 
     public Object getModuleBuilder()
     {
-        return barrier.withRead(provideModuleBuilder);
+        return BARRIER.withRead(provideModuleBuilder);
     }
 
     private Object constructModuleBuilder()



Mime
View raw message