You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2009/12/30 19:19:05 UTC

svn commit: r894687 - in /myfaces/extensions/scripting/trunk/core: core/src/main/java/org/apache/myfaces/scripting/api/ core/src/main/java/org/apache/myfaces/scripting/loaders/java/ core/src/main/java/org/apache/myfaces/scripting/refresh/ core/src/main...

Author: werpu
Date: Wed Dec 30 18:19:04 2009
New Revision: 894687

URL: http://svn.apache.org/viewvc?rev=894687&view=rev
Log:
ongoing works on making the lib thread safe

Modified:
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/RecompiledClassLoader.java
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/RefreshContext.java
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/servlet/ScriptingServletFilter.java
    myfaces/extensions/scripting/trunk/core/myfaces12-extensions/src/main/java/org/apache/myfaces/scripting/jsf/dynamicdecorators/implemetations/RenderkitProxy.java

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java?rev=894687&r1=894686&r2=894687&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java Wed Dec 30 18:19:04 2009
@@ -139,7 +139,7 @@
             //if not tained then we can recycle the last class loaded
             return metadata.getAClass();
         }
-        synchronized (RefreshContext.RELOAD_SYNC_MONITOR) {
+        synchronized (RefreshContext.COMPILE_SYNC_MONITOR) {
             //another chance just in case someone has reloaded between
             //the last if and synchronized, that way we can reduce the number of waiting threads
             if (!metadata.isTainted()) {
@@ -170,7 +170,7 @@
                  * the reload has to be performed synchronized
                  * hence there is no chance to do it unsynchronized
                  */
-                synchronized (RefreshContext.RELOAD_SYNC_MONITOR) {
+                synchronized (RefreshContext.COMPILE_SYNC_MONITOR) {
                     metadata = classMap.get(className);
                     if (metadata != null) {
                         return reloadScriptingClass(metadata.getAClass());
@@ -188,7 +188,6 @@
         return null;
     }
 
-   
 
     protected Log getLog() {
         return LogFactory.getLog(this.getClass());
@@ -220,7 +219,6 @@
 
     public abstract boolean isDynamic(Class clazz);
 
-   
 
     public ScriptingWeaver getWeaverInstance(Class weaverClass) {
         if (getClass().equals(weaverClass)) return this;
@@ -233,12 +231,17 @@
 
 
     public void requestRefresh() {
+        //needed?
+
+
         if (WeavingContext.getRefreshContext().isRecompileRecommended(getScriptingEngine())) {
             // we set a lock over the compile and bean refresh
             //and an inner check again to avoid unneeded compile triggers
             synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
                 if (WeavingContext.getRefreshContext().isRecompileRecommended(getScriptingEngine())) {
-                    recompileRefresh();
+
+                        recompileRefresh();
+
                     return;
                 }
             }
@@ -260,7 +263,9 @@
     }
 
     private void recompileRefresh() {
-        fullRecompile();
+        synchronized(RefreshContext.COMPILE_SYNC_MONITOR) {
+            fullRecompile();
+        }
 
         refreshAllManagedBeans();
     }
@@ -362,42 +367,46 @@
      * other users have to drop their non application scoped beans as well!
      */
     private void refreshPersonalScopedBeans() {
+        //the refreshing is only allowed if no compile is in progress
+        //and vice versa
+
+        synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
+            Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
+            //the map is immutable but in between scanning might change it so we make a full copy of the map
 
-        Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
-        //the map is immutable but in between scanning might change it so we make a full copy of the map
+            //We can synchronized the refresh, but if someone alters
+            //the bean map from outside we still get race conditions
+            //But for most cases this mutex should be enough
 
-        //We can synchronized the refresh, but if someone alters
-        //the bean map from outside we still get race conditions
-        //But for most cases this mutex should be enough
+            Map<String, ManagedBean> workCopy = null;
 
-        Map<String, ManagedBean> workCopy = null;
-        synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
             workCopy = makeSnapshot(mbeans);
-        }
 
-        for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
 
-            Class managedBeanClass = entry.getValue().getManagedBeanClass();
-            if (WeavingContext.isDynamic(managedBeanClass)) {
-                String scope = entry.getValue().getManagedBeanScope();
-
-                if (scope != null && !scope.equalsIgnoreCase(SCOPE_APPLICATION)) {
-                    if (scope.equalsIgnoreCase(SCOPE_REQUEST)) {
-                        //request, nothing has to be done here
-                        return;
-                    }
-                    synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
+            for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
+
+                Class managedBeanClass = entry.getValue().getManagedBeanClass();
+                if (WeavingContext.isDynamic(managedBeanClass)) {
+                    String scope = entry.getValue().getManagedBeanScope();
+
+                    if (scope != null && !scope.equalsIgnoreCase(SCOPE_APPLICATION)) {
+                        if (scope.equalsIgnoreCase(SCOPE_REQUEST)) {
+                            //request, nothing has to be done here
+                            return;
+                        }
+
                         if (scope.equalsIgnoreCase(SCOPE_SESSION)) {
                             FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(entry.getValue().getManagedBeanName());
                         } else {
                             removeCustomScopedBean(entry.getValue());
                         }
+
                     }
-                }
 
+                }
             }
-
             updateBeanRefreshTime();
+
         }
 
     }
@@ -409,6 +418,7 @@
      *
      * @param bean
      */
+
     private void removeBeanReferences(ManagedBean bean) {
         if (getLog().isInfoEnabled()) {
             getLog().info("[EXT-SCRIPTING] JavaScriptingWeaver.removeBeanReferences(" + bean.getManagedBeanName() + ")");

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/RecompiledClassLoader.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/RecompiledClassLoader.java?rev=894687&r1=894686&r2=894687&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/RecompiledClassLoader.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/RecompiledClassLoader.java Wed Dec 30 18:19:04 2009
@@ -24,6 +24,7 @@
 import org.apache.myfaces.scripting.core.util.ClassUtils;
 import org.apache.myfaces.scripting.core.util.FileUtils;
 import org.apache.myfaces.scripting.core.util.WeavingContext;
+import org.apache.myfaces.scripting.refresh.RefreshContext;
 import org.apache.myfaces.scripting.refresh.ReloadingMetadata;
 
 import java.io.File;
@@ -100,12 +101,18 @@
             }
 
             FileInputStream iStream = null;
-            int fileLength = (int) target.length();
-            byte[] fileContent = new byte[fileLength];
 
+            int fileLength = -1;
+            byte[] fileContent = null;
             try {
-                iStream = new FileInputStream(target);
-                iStream.read(fileContent);
+                //we cannot load while a compile is in progress
+                //we have to wait until it is one
+                synchronized(RefreshContext.COMPILE_SYNC_MONITOR) {
+                    fileLength = (int) target.length();
+                    fileContent = new byte[fileLength];
+                    iStream = new FileInputStream(target);
+                    iStream.read(fileContent);
+                }
                 // Erzeugt aus dem byte Feld ein Class Object.
                 Class retVal = null;
 

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/RefreshContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/RefreshContext.java?rev=894687&r1=894686&r2=894687&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/RefreshContext.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/RefreshContext.java Wed Dec 30 18:19:04 2009
@@ -22,6 +22,7 @@
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @author Werner Punz (latest modification by $Author$)
@@ -54,31 +55,26 @@
      */
     volatile FileChangedDaemon daemon = FileChangedDaemon.getInstance();
 
-    /*
-     * we have to keep the component data as shadow data reachable
-     * from various parts of the system to resolve
-     * the component <-> renderer dependencies
-     * we do not resolve the dependencies between the tag handlers
-     * and the components for now
-     *
-     * resolving those dependencies means
-     * renderer changes <-> taint all component classes which use
-     * the renderer
-     *
-     * component changes <-> taint all renderer classes as well
-     *
-     * This is needed to avoid intra component <-> renderer
-     * classcast exceptions
-     *
-     * the content of this map is the component class
-     * and the value is the renderer class
+
+    /**
+     * the bean synchronisation has to be dealt with
+     * differently, we have two volatile points in the lifecycle
+     * one being the compile the other one the bean refresh
+     * the refresh can only happen outside of a compile cycle
+     * and also a global refresh has to be atomic and no other
+     * refreshes should happen
      */
-    private volatile Map<String, String> _componentRendererDependencies = new ConcurrentHashMap<String, String>();
-    private volatile Map<String, String> _rendererComponentDependencies = new ConcurrentHashMap<String, String>();
+    public volatile static Boolean BEAN_SYNC_MONITOR = new Boolean(true);
 
+    /**
+     * second synchronisation monitor
+     * all other artefacts can only be refreshed outside of a
+     * compile cycle othwise the classloader would get
+     * half finished compile states to load
+     */
+    public volatile static Boolean COMPILE_SYNC_MONITOR = new Boolean(true);
 
-    public volatile static Boolean BEAN_SYNC_MONITOR = new Boolean(true);
-    public volatile static Boolean RELOAD_SYNC_MONITOR = new Boolean(true);
+    private volatile AtomicInteger currentlyRunningRequests = null;
 
     public long getPersonalScopedBeanRefresh() {
         return personalScopedBeanRefresh;
@@ -134,19 +130,30 @@
      * @param engineType
      * @return
      */
-    public static boolean isComileAllowed(int engineType) {
-        //TODO implement synchronized locking logic to avoid
-        //race conditions in multiuser environments
-        return true;
-    }
+    public boolean isComileAllowed(int engineType) {
 
-    public Map<String, String> getComponentRendererDependencies() {
-        return _componentRendererDependencies;
+        return getCurrentlyRunningRequests().equals(1);
     }
 
+ 
+    /**
+     * getter for our request counter
+     * we need this variable to keep a lock
+     * on the number of requests
+     * we only can compile if the currently
+     * running request is the only one currently
+     * active, to keep the compilation results in sync
+     *
+     * @return the request counter holder which is an atomic integer
+     *
+     * probably deprecred
+     */
+    public AtomicInteger getCurrentlyRunningRequests() {
+        return currentlyRunningRequests;
+    }
 
-    public Map<String, String> getRendererComponentDependencies() {
-        return _rendererComponentDependencies;
+    public void setCurrentlyRunningRequests(AtomicInteger currentlyRunning) {
+        currentlyRunningRequests = currentlyRunning;
     }
 
 }

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/servlet/ScriptingServletFilter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/servlet/ScriptingServletFilter.java?rev=894687&r1=894686&r2=894687&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/servlet/ScriptingServletFilter.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/servlet/ScriptingServletFilter.java Wed Dec 30 18:19:04 2009
@@ -48,12 +48,18 @@
         WeavingContext.setWeaver(context.getAttribute("ScriptingWeaver"));
         WeavingContext.setRefreshContext((RefreshContext) context.getAttribute("RefreshContext"));
         WeavingContext.setConfiguration((Configuration) context.getAttribute(ScriptingConst.CTX_CONFIGURATION));
+        WeavingContext.getRefreshContext().setCurrentlyRunningRequests(getRequestCnt());
 
-        filterChain.doFilter(servletRequest, servletResponse);
+
+        try {
+            filterChain.doFilter(servletRequest, servletResponse);
+        } finally {
+            markRequestEnd();
+        }
     }
 
     public void destroy() {
-        markRequestEnd();
+
         WeavingContext.clean();
     }
 
@@ -73,8 +79,4 @@
         return getRequestCnt().decrementAndGet();
     }
 
-    private int concurrentRequests() {
-        return getRequestCnt().get();
-    }
-
 }
\ No newline at end of file

Modified: myfaces/extensions/scripting/trunk/core/myfaces12-extensions/src/main/java/org/apache/myfaces/scripting/jsf/dynamicdecorators/implemetations/RenderkitProxy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/myfaces12-extensions/src/main/java/org/apache/myfaces/scripting/jsf/dynamicdecorators/implemetations/RenderkitProxy.java?rev=894687&r1=894686&r2=894687&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/myfaces12-extensions/src/main/java/org/apache/myfaces/scripting/jsf/dynamicdecorators/implemetations/RenderkitProxy.java (original)
+++ myfaces/extensions/scripting/trunk/core/myfaces12-extensions/src/main/java/org/apache/myfaces/scripting/jsf/dynamicdecorators/implemetations/RenderkitProxy.java Wed Dec 30 18:19:04 2009
@@ -55,13 +55,6 @@
         //renderers itself are flyweight patterns which means they are shared over objects
         renderer = (Renderer) reloadInstance(renderer, ScriptingConst.ARTEFACT_TYPE_RENDERER);
         _delegate.addRenderer(componentFamily, rendererType, renderer);
-
-        /**
-         * we save the component family and the renderer class name
-         * so that if a component of
-         */
-
-        WeavingContext.getRefreshContext().getRendererComponentDependencies().put(renderer.getClass().getName(), componentFamily);
     }
 
     public Renderer getRenderer(String componentFamily, String rendererType) {