Author: jcompagner
Date: Wed Mar 17 22:47:37 2010
New Revision: 924540
URL: http://svn.apache.org/viewvc?rev=924540&view=rev
Log:
Pagemap is locked forever with some Page serialization exceptions
Issue: WICKET-2075
Modified:
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/Session.java
Modified:
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/Session.java
URL:
http://svn.apache.org/viewvc/wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/Session.java?rev=924540&r1=924539&r2=924540&view=diff
==============================================================================
---
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/Session.java
(original)
+++
wicket/branches/wicket-1.4.x/wicket/src/main/java/org/apache/wicket/Session.java
Wed Mar 17 22:47:37 2010
@@ -1405,97 +1405,112 @@ public abstract class Session implements
{
for (int i = 0; i < touchedPages.size(); i++)
{
- Page page = touchedPages.get(i);
- // page must be detached before it gets stored
- page.detach();
- page.getPageMap().put(page);
+ try
+ {
+ Page page = touchedPages.get(i);
+ // page must be detached before it gets
stored
+ page.detach();
+ page.getPageMap().put(page);
+ }
+ catch (Throwable t)
+ {
+ // catch runtime and errors so that the
next page is not detached/serialized and
+ // the pagemap released. (see below)
+ log.error("Exception when
detaching/serializing page", t);
+ }
dirty = true;
}
}
- // If state is dirty
- if (dirty)
+ try
{
- // State is no longer dirty
- dirty = false;
+ // If state is dirty
+ if (dirty)
+ {
+ // State is no longer dirty
+ dirty = false;
- // Set attribute.
- setAttribute(SESSION_ATTRIBUTE_NAME, this);
- }
- else
- {
- if (log.isDebugEnabled())
+ // Set attribute.
+ setAttribute(SESSION_ATTRIBUTE_NAME, this);
+ }
+ else
{
- log.debug("update: Session not dirty.");
+ if (log.isDebugEnabled())
+ {
+ log.debug("update: Session not dirty.");
+ }
}
- }
- List<IClusterable> dirtyObjects = Session.dirtyObjects.get();
- Session.dirtyObjects.set(null);
+ List<IClusterable> dirtyObjects =
Session.dirtyObjects.get();
+ Session.dirtyObjects.set(null);
- Map<String, Object> tempMap = new HashMap<String, Object>();
+ Map<String, Object> tempMap = new HashMap<String,
Object>();
- // Go through all dirty entries, replicating any dirty objects
- if (dirtyObjects != null)
- {
- for (final Iterator<IClusterable> iterator =
dirtyObjects.iterator(); iterator.hasNext();)
+ // Go through all dirty entries, replicating any dirty
objects
+ if (dirtyObjects != null)
{
- String attribute = null;
- Object object = iterator.next();
- if (object instanceof Page)
+ for (final Iterator<IClusterable> iterator =
dirtyObjects.iterator(); iterator.hasNext();)
{
- final Page page = (Page)object;
- if (page.isPageStateless())
+ String attribute = null;
+ Object object = iterator.next();
+ if (object instanceof Page)
{
- // check, can it be that
stateless pages where added to
- // the session?
- // and should be removed now?
- continue;
+ final Page page = (Page)object;
+ if (page.isPageStateless())
+ {
+ // check, can it be
that stateless pages where added to
+ // the session?
+ // and should be
removed now?
+ continue;
+ }
+ attribute =
page.getPageMap().attributeForId(page.getNumericId());
+ if (getAttribute(attribute) ==
null)
+ {
+ // page removed by
another thread. don't add it again.
+ continue;
+ }
+ object = page.getPageMapEntry();
}
- attribute =
page.getPageMap().attributeForId(page.getNumericId());
- if (getAttribute(attribute) == null)
+ else if (object instanceof IPageMap)
{
- // page removed by another
thread. don't add it again.
- continue;
+ attribute =
attributeForPageMapName(((IPageMap)object).getName());
}
- object = page.getPageMapEntry();
- }
- else if (object instanceof IPageMap)
- {
- attribute =
attributeForPageMapName(((IPageMap)object).getName());
- }
- // we might override some attributes, so we use
a temporary map
- // and then just copy the last values to real
sesssion
- tempMap.put(attribute, object);
+ // we might override some attributes,
so we use a temporary map
+ // and then just copy the last values
to real sesssion
+ tempMap.put(attribute, object);
+ }
}
- }
- // in case we have dirty attributes, set them to session
- if (tempMap.isEmpty() == false)
- {
- for (Entry<String, Object> entry : tempMap.entrySet())
+ // in case we have dirty attributes, set them to session
+ if (tempMap.isEmpty() == false)
{
- setAttribute(entry.getKey(), entry.getValue());
+ for (Entry<String, Object> entry :
tempMap.entrySet())
+ {
+ setAttribute(entry.getKey(),
entry.getValue());
+ }
}
}
-
- if (pageMapsUsedInRequest != null)
+ finally
{
- synchronized (pageMapsUsedInRequest)
+
+ if (pageMapsUsedInRequest != null)
{
- Thread t = Thread.currentThread();
- Iterator<Entry<IPageMap,
PageMapsUsedInRequestEntry>> it = pageMapsUsedInRequest.entrySet()
- .iterator();
- while (it.hasNext())
+ synchronized (pageMapsUsedInRequest)
{
- Entry<IPageMap,
PageMapsUsedInRequestEntry> entry = it.next();
- if ((entry.getValue()).thread == t)
+ Thread t = Thread.currentThread();
+ Iterator<Entry<IPageMap,
PageMapsUsedInRequestEntry>> it = pageMapsUsedInRequest.entrySet()
+ .iterator();
+ while (it.hasNext())
{
- it.remove();
+ Entry<IPageMap,
PageMapsUsedInRequestEntry> entry = it.next();
+ if ((entry.getValue()).thread
== t)
+ {
+ it.remove();
+ }
}
+ pageMapsUsedInRequest.notifyAll();
}
- pageMapsUsedInRequest.notifyAll();
}
}
}