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) {