You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2012/06/21 18:24:09 UTC

git commit: TAP5-1929: Convert more synchronized blocks to use LockSupport

Updated Branches:
  refs/heads/5.3 be4b9afb8 -> 09be89ed3


TAP5-1929: Convert more synchronized blocks to use LockSupport


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/09be89ed
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/09be89ed
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/09be89ed

Branch: refs/heads/5.3
Commit: 09be89ed3244fff4283612b6a333abd3857c1812
Parents: be4b9af
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Thu Jun 21 09:23:01 2012 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Thu Jun 21 09:23:53 2012 -0700

----------------------------------------------------------------------
 .../ApplicationMessageCatalogObjectProvider.java   |   54 ++++++++++-----
 .../tapestry5/internal/structure/PageImpl.java     |   12 +++-
 .../internal/AbstractReloadableObjectCreator.java  |   32 +++++++--
 .../internal/services/CachingObjectCreator.java    |   41 +++++++++--
 4 files changed, 104 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/09be89ed/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java
index bedbd6a..5c391e9 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ApplicationMessageCatalogObjectProvider.java
@@ -1,4 +1,4 @@
-// Copyright 2010, 2011 The Apache Software Foundation
+// Copyright 2010, 2011, 2012 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,30 +14,27 @@
 
 package org.apache.tapestry5.internal.services;
 
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.tapestry5.ioc.AnnotationProvider;
-import org.apache.tapestry5.ioc.Messages;
-import org.apache.tapestry5.ioc.ObjectCreator;
-import org.apache.tapestry5.ioc.ObjectLocator;
-import org.apache.tapestry5.ioc.ObjectProvider;
+import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.LockSupport;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.ioc.services.ThreadLocale;
 import org.apache.tapestry5.services.InvalidationListener;
 import org.apache.tapestry5.services.messages.ComponentMessagesSource;
 
+import java.util.Locale;
+import java.util.Map;
+
 /**
  * Allows for injection of the global application message catalog into services. The injected value
  * is, in fact, a proxy. Each method access of the proxy will determine the current thread's locale, and delegate
  * to the actual global message catalog for that particular locale. There's caching to keep it reasonably
  * efficient.
- * 
- * @since 5.2.0
+ *
  * @see ComponentMessagesSource#getApplicationCatalog(Locale)
+ * @since 5.2.0
  */
-public class ApplicationMessageCatalogObjectProvider implements ObjectProvider, InvalidationListener
+public class ApplicationMessageCatalogObjectProvider extends LockSupport implements ObjectProvider, InvalidationListener
 {
     private final ObjectLocator objectLocator;
 
@@ -65,7 +62,9 @@ public class ApplicationMessageCatalogObjectProvider implements ObjectProvider,
 
             return messages;
         }
-    };
+    }
+
+    ;
 
     public ApplicationMessageCatalogObjectProvider(ObjectLocator locator)
     {
@@ -78,10 +77,30 @@ public class ApplicationMessageCatalogObjectProvider implements ObjectProvider,
      * of normal IoC dependency injection and adopt a lookup strategy based on the ObjectLocator. Further,
      * we have to be careful about multi-threading issues.
      */
-    private synchronized Messages getProxy()
+    private Messages getProxy()
     {
-        if (proxy == null)
+        try
         {
+            acquireReadLock();
+
+            if (proxy == null)
+            {
+                createProxy();
+            }
+
+            return proxy;
+        } finally
+        {
+            releaseReadLock();
+        }
+    }
+
+    private void createProxy()
+    {
+        try
+        {
+            upgradeReadLockToWriteLock();
+
             this.messagesSource = objectLocator.getService(ComponentMessagesSource.class);
             this.threadLocale = objectLocator.getService(ThreadLocale.class);
 
@@ -95,9 +114,10 @@ public class ApplicationMessageCatalogObjectProvider implements ObjectProvider,
             // and invalidation occurs.
 
             messagesSource.getInvalidationEventHub().addInvalidationListener(this);
+        } finally
+        {
+            downgradeWriteLockToReadLock();
         }
-
-        return proxy;
     }
 
     public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/09be89ed/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
index a9304e6..9ef1842 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
@@ -56,7 +56,9 @@ public class PageImpl implements Page
 
     private final OneShotLock verifyListenerLocks = new OneShotLock();
 
-    private final Map<String, ComponentPageElement> idToComponent = CollectionFactory.newCaseInsensitiveMap();
+    // May end up with multiple mappings for the same id (with different case) to the same component.
+    // That's OK.
+    private final Map<String, ComponentPageElement> idToComponent = CollectionFactory.newConcurrentMap();
 
     private Stats stats;
 
@@ -109,12 +111,14 @@ public class PageImpl implements Page
         return String.format("Page[%s %s]", name, selector.toShortString());
     }
 
-    public synchronized ComponentPageElement getComponentElementByNestedId(String nestedId)
+    public ComponentPageElement getComponentElementByNestedId(String nestedId)
     {
         assert nestedId != null;
 
         if (nestedId.equals(""))
+        {
             return rootElement;
+        }
 
         ComponentPageElement element = idToComponent.get(nestedId);
 
@@ -246,7 +250,9 @@ public class PageImpl implements Page
     public void persistFieldChange(ComponentResources resources, String fieldName, Object newValue)
     {
         if (!loadComplete)
+        {
             throw new RuntimeException(StructureMessages.persistChangeBeforeLoadComplete());
+        }
 
         persistentFieldManager.postChange(name, resources, fieldName, newValue);
     }
@@ -254,7 +260,9 @@ public class PageImpl implements Page
     public Object getFieldChange(String nestedId, String fieldName)
     {
         if (!fieldBundle.exists())
+        {
             fieldBundle.set(persistentFieldManager.gatherChanges(name));
+        }
 
         return fieldBundle.get().getValue(nestedId, fieldName);
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/09be89ed/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
index 357c66c..80873e5 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractReloadableObjectCreator.java
@@ -26,6 +26,7 @@ import org.apache.tapestry5.ioc.OperationTracker;
 import org.apache.tapestry5.ioc.ReloadAware;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.LockSupport;
 import org.apache.tapestry5.ioc.internal.util.URLChangeTracker;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.services.UpdateListener;
@@ -39,7 +40,7 @@ import java.net.URL;
 import java.util.Set;
 
 @SuppressWarnings("all")
-public abstract class AbstractReloadableObjectCreator implements ObjectCreator, UpdateListener, ClassLoaderDelegate
+public abstract class AbstractReloadableObjectCreator extends LockSupport implements ObjectCreator, UpdateListener, ClassLoaderDelegate
 {
     private final ClassLoader baseClassLoader;
 
@@ -111,14 +112,21 @@ public abstract class AbstractReloadableObjectCreator implements ObjectCreator,
         return false;
     }
 
-    public synchronized Object createObject()
+    public Object createObject()
     {
-        if (instance == null)
+        try
         {
-            instance = createInstance();
-        }
+            acquireReadLock();
+            if (instance == null)
+            {
+                instance = createInstance();
+            }
 
-        return instance;
+            return instance;
+        } finally
+        {
+            releaseReadLock();
+        }
     }
 
     private Object createInstance()
@@ -127,9 +135,17 @@ public abstract class AbstractReloadableObjectCreator implements ObjectCreator,
         {
             public Object invoke()
             {
-                Class reloadedClass = reloadImplementationClass();
+                try
+                {
+                    upgradeReadLockToWriteLock();
+
+                    Class reloadedClass = reloadImplementationClass();
 
-                return createInstance(reloadedClass);
+                    return createInstance(reloadedClass);
+                } finally
+                {
+                    downgradeWriteLockToReadLock();
+                }
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/09be89ed/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CachingObjectCreator.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CachingObjectCreator.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CachingObjectCreator.java
index a1ff31a..8a0cb22 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CachingObjectCreator.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CachingObjectCreator.java
@@ -1,4 +1,4 @@
-// Copyright 2009, 2011 The Apache Software Foundation
+// Copyright 2009, 2011, 2012 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,12 +15,13 @@
 package org.apache.tapestry5.ioc.internal.services;
 
 import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.internal.util.LockSupport;
 
 /**
  * An {@link org.apache.tapestry5.ioc.ObjectCreator} that delegates to another
  * {@link org.apache.tapestry5.ioc.ObjectCreator} and caches the result.
  */
-public class CachingObjectCreator<T> implements ObjectCreator<T>
+public class CachingObjectCreator<T> extends LockSupport implements ObjectCreator<T>
 {
     private boolean cached;
 
@@ -33,15 +34,39 @@ public class CachingObjectCreator<T> implements ObjectCreator<T>
         this.delegate = delegate;
     }
 
-    public synchronized T createObject()
+    public T createObject()
     {
-        if (!cached)
+        try
         {
-            cachedValue = delegate.createObject();
-            cached = true;
-            delegate = null;
+            acquireReadLock();
+
+            if (!cached)
+            {
+                cacheValueFromDelegate();
+            }
+
+            return cachedValue;
+        } finally
+        {
+            releaseReadLock();
         }
+    }
 
-        return cachedValue;
+    private void cacheValueFromDelegate()
+    {
+        try
+        {
+            upgradeReadLockToWriteLock();
+
+            if (!cached)
+            {
+                cachedValue = delegate.createObject();
+                cached = true;
+                delegate = null;
+            }
+        } finally
+        {
+            downgradeWriteLockToReadLock();
+        }
     }
 }