Index: core/src/com/icesoft/faces/context/BridgeFacesContext.java =================================================================== --- core/src/com/icesoft/faces/context/BridgeFacesContext.java (revision 124) +++ core/src/com/icesoft/faces/context/BridgeFacesContext.java (working copy) @@ -88,6 +88,7 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; public class @@ -131,6 +132,7 @@ viewRoot = null; } }; + private final ReentrantLock serializerLock = new ReentrantLock(); private static Constructor jsfUnitConstructor; private static String jsfUnitClass; @@ -313,16 +315,34 @@ return responseWriter = new DOMResponseWriter(this, domSerializer, configuration, jsCodeURIs, cssRuleURIs, blockingRequestHandlerContext); } + void lockSerializer() { + serializerLock.lock(); + } + + void unlockSerializer() { + serializerLock.unlock(); + } + public void switchToNormalMode() throws Exception { - externalContext.switchToNormalMode(); - domSerializer = new SaveCurrentDocument(new NormalModeSerializer(this, externalContext.getWriter("UTF-8"))); + lockSerializer(); + try { + externalContext.switchToNormalMode(); + domSerializer = new SaveCurrentDocument(new NormalModeSerializer(this, externalContext.getWriter("UTF-8"))); + } finally { + unlockSerializer(); + } } public void switchToPushMode() throws Exception { - //collect bundles put by Tag components when the page is parsed - bundles = externalContext.collectBundles(); - externalContext.switchToPushMode(); - domSerializer = new SaveCurrentDocument(new PushModeSerializer(documentStore, view, this, viewNumber)); + lockSerializer(); + try { + //collect bundles put by Tag components when the page is parsed + bundles = externalContext.collectBundles(); + externalContext.switchToPushMode(); + domSerializer = new SaveCurrentDocument(new PushModeSerializer(documentStore, view, this, viewNumber)); + } finally { + unlockSerializer(); + } } public UIViewRoot getViewRoot() { @@ -336,7 +356,7 @@ public void setViewRoot(UIViewRoot viewRoot) { // #3424. Allow viewRoot to be set to null. On page reload, this object - // is reused, but viewRoot must be nullable + // is reused, but viewRoot must be nullable this.viewRoot = viewRoot; if (viewRoot != null) { lastViewID = viewRoot.getViewId(); @@ -529,7 +549,7 @@ } } if (found) { - // For some reason, our multiple checkbox + // For some reason, our multiple checkbox // components use checked="true", while // our single checkbox components use // checked="checked". The latter complying @@ -868,7 +888,7 @@ void save(Document document) throws IOException; /* Keep the Document in a more efficient form for - fast loading + fast loading */ void cache(Document document) throws IOException; Index: core/src/com/icesoft/faces/context/NormalModeSerializer.java =================================================================== --- core/src/com/icesoft/faces/context/NormalModeSerializer.java (revision 124) +++ core/src/com/icesoft/faces/context/NormalModeSerializer.java (working copy) @@ -53,7 +53,16 @@ } public void serialize(Document document) throws IOException { + context.lockSerializer(); try { + doSerialization(document); + } finally { + context.unlockSerializer(); + } + } + + private void doSerialization(Document document) throws IOException { + try { if (context.isContentIncluded()) { if (log.isDebugEnabled()) { log.debug("treating request as a fragment"); Index: core/src/com/icesoft/faces/context/PushModeSerializer.java =================================================================== --- core/src/com/icesoft/faces/context/PushModeSerializer.java (revision 124) +++ core/src/com/icesoft/faces/context/PushModeSerializer.java (working copy) @@ -66,6 +66,15 @@ } public void serialize(final Document document) throws IOException { + context.lockSerializer(); + try { + doSerialization(document); + } finally { + context.unlockSerializer(); + } + } + + private void doSerialization(Document document) throws IOException { Node[] changed = DOMUtils.domDiff(store.load(), document); HashMap depthMaps = new HashMap(); for (int i = 0; i < changed.length; i++) {