Return-Path: Delivered-To: apmail-myfaces-commits-archive@www.apache.org Received: (qmail 81806 invoked from network); 16 Dec 2009 21:15:10 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 16 Dec 2009 21:15:10 -0000 Received: (qmail 12898 invoked by uid 500); 16 Dec 2009 21:15:10 -0000 Delivered-To: apmail-myfaces-commits-archive@myfaces.apache.org Received: (qmail 12777 invoked by uid 500); 16 Dec 2009 21:15:10 -0000 Mailing-List: contact commits-help@myfaces.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "MyFaces Development" Delivered-To: mailing list commits@myfaces.apache.org Received: (qmail 12768 invoked by uid 99); 16 Dec 2009 21:15:10 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Dec 2009 21:15:10 +0000 X-ASF-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Dec 2009 21:15:08 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 34E5323889D2; Wed, 16 Dec 2009 21:14:48 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r891427 - /myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java Date: Wed, 16 Dec 2009 21:14:45 -0000 To: commits@myfaces.apache.org From: werpu@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091216211448.34E5323889D2@eris.apache.org> Author: werpu Date: Wed Dec 16 21:14:41 2009 New Revision: 891427 URL: http://svn.apache.org/viewvc?rev=891427&view=rev Log: added mutexes on the correct parts of the system so that the iteration over the beans does not happen at the same time as the alteration Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.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=891427&r1=891426&r2=891427&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 16 21:14:41 2009 @@ -262,18 +262,22 @@ return;//no npe allowed } Set tainted = new HashSet(); - for (Map.Entry it : WeavingContext.getFileChangedDaemon().getClassMap().entrySet()) { - if (it.getValue().getScriptingEngine() == getScriptingEngine() && it.getValue().isTainted()) { - tainted.add(it.getKey()); + synchronized (this) { + for (Map.Entry it : WeavingContext.getFileChangedDaemon().getClassMap().entrySet()) { + if (it.getValue().getScriptingEngine() == getScriptingEngine() && it.getValue().isTainted()) { + tainted.add(it.getKey()); + } } } if (tainted.size() > 0) { boolean managedBeanTainted = false; //We now have to check if the tainted classes belong to the managed beans Set managedBeanClasses = new HashSet(); - Map mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans(); - for (Map.Entry entry : mbeans.entrySet()) { - managedBeanClasses.add(entry.getValue().getManagedBeanClassName()); + synchronized (this) { + Map mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans(); + for (Map.Entry entry : mbeans.entrySet()) { + managedBeanClasses.add(entry.getValue().getManagedBeanClassName()); + } } for (String taintedClass : tainted) { if (managedBeanClasses.contains(taintedClass)) { @@ -287,20 +291,22 @@ getLog().info("[EXT-SCRIPTING] Tainting all beans to avoid classcast exceptions"); if (managedBeanTainted) { - Map workCopy = makeSnapshot(mbeans); + synchronized (this) { + Map workCopy = makeSnapshot(mbeans); - for (Map.Entry entry : workCopy.entrySet()) { - Class managedBeanClass = entry.getValue().getManagedBeanClass(); - if (WeavingContext.isDynamic(managedBeanClass)) { - //managed bean class found we drop the class from our session - removeBeanReferences(entry.getValue()); - } - //one bean tainted we have to taint all dynamic beans otherwise we will get classcast - //exceptions - getLog().info("[EXT-SCRIPTING] Tainting "); - ReloadingMetadata metaData = WeavingContext.getFileChangedDaemon().getClassMap().get(managedBeanClass.getName()); - if (metaData != null) { - metaData.setTainted(true); + for (Map.Entry entry : workCopy.entrySet()) { + Class managedBeanClass = entry.getValue().getManagedBeanClass(); + if (WeavingContext.isDynamic(managedBeanClass)) { + //managed bean class found we drop the class from our session + removeBeanReferences(entry.getValue()); + } + //one bean tainted we have to taint all dynamic beans otherwise we will get classcast + //exceptions + getLog().info("[EXT-SCRIPTING] Tainting "); + ReloadingMetadata metaData = WeavingContext.getFileChangedDaemon().getClassMap().get(managedBeanClass.getName()); + if (metaData != null) { + metaData.setTainted(true); + } } } @@ -318,7 +324,7 @@ * @param mbeans * @return */ - private synchronized Map makeSnapshot(Map mbeans) { + private Map makeSnapshot(Map mbeans) { Map workCopy = new HashMap(mbeans.size()); for (Map.Entry entry : mbeans.entrySet()) { workCopy.put(entry.getKey(), entry.getValue()); @@ -346,33 +352,39 @@ */ private void refreshPersonalScopedBeans() { - Map 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 workCopy = makeSnapshot(mbeans); - - for (Map.Entry entry : workCopy.entrySet()) { - - Class managedBeanClass = entry.getValue().getManagedBeanClass(); - if (WeavingContext.isDynamic(managedBeanClass)) { - String scope = entry.getValue().getManagedBeanScope(); + synchronized (this) { + Map 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 - 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()); + //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 workCopy = makeSnapshot(mbeans); + + for (Map.Entry 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(); } } - updateBeanRefreshTime(); } /**