Updated Branches: refs/heads/code-coverage-jacoco 8cac63426 -> 5affeb95b
WICKET-5316: fixed synchronization problem in page access Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/0575a96e Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/0575a96e Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/0575a96e Branch: refs/heads/code-coverage-jacoco Commit: 0575a96e06dcab2fe593f0083bc23e00ed0db437 Parents: 706d7ac Author: Emond Papegaaij <[email protected]> Authored: Wed Aug 14 14:18:49 2013 +0200 Committer: Emond Papegaaij <[email protected]> Committed: Wed Aug 14 14:18:49 2013 +0200 ---------------------------------------------------------------------- .../wicket/page/PageAccessSynchronizer.java | 70 +++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/0575a96e/wicket-core/src/main/java/org/apache/wicket/page/PageAccessSynchronizer.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/page/PageAccessSynchronizer.java b/wicket-core/src/main/java/org/apache/wicket/page/PageAccessSynchronizer.java index 721b584..da1f12b 100644 --- a/wicket-core/src/main/java/org/apache/wicket/page/PageAccessSynchronizer.java +++ b/wicket-core/src/main/java/org/apache/wicket/page/PageAccessSynchronizer.java @@ -114,23 +114,7 @@ public class PageAccessSynchronizer implements Serializable long remaining = remaining(start, timeout); if (remaining > 0) { - synchronized (previous) - { - if (isDebugEnabled) - { - logger.debug("{} waiting for lock to page {} for {}", new Object[] { - thread.getName(), pageId, Duration.milliseconds(remaining) }); - } - try - { - previous.wait(remaining); - } - catch (InterruptedException e) - { - // TODO better exception - throw new RuntimeException(e); - } - } + previous.waitForRelease(remaining, isDebugEnabled); } } } @@ -212,14 +196,7 @@ public class PageAccessSynchronizer implements Serializable lock.pageId); } // if any locks were removed notify threads waiting for a lock - synchronized (lock) - { - if (isDebugEnabled) - { - logger.debug("'{}' notifying blocked threads", thread.getName()); - } - lock.notifyAll(); - } + lock.markReleased(isDebugEnabled); if (pageId != null) { // unlock just the page with the specified id @@ -301,6 +278,8 @@ public class PageAccessSynchronizer implements Serializable /** thread that owns the lock */ private final Thread thread; + private boolean released = false; + /** * Constructor * @@ -328,5 +307,46 @@ public class PageAccessSynchronizer implements Serializable { return thread; } + + final synchronized void waitForRelease(long remaining, boolean isDebugEnabled) + { + if (released) + { + // the thread holding the lock released it before we were able to wait for the + // release + if (isDebugEnabled) + { + logger.debug( + "lock for page with id {} no longer locked by {}, falling through", pageId, + thread.getName()); + } + return; + } + + if (isDebugEnabled) + { + logger.debug("{} waiting for lock to page {} for {}", + new Object[] { thread.getName(), pageId, Duration.milliseconds(remaining) }); + } + try + { + wait(remaining); + } + catch (InterruptedException e) + { + // TODO better exception + throw new RuntimeException(e); + } + } + + final synchronized void markReleased(boolean isDebugEnabled) + { + if (isDebugEnabled) + { + logger.debug("'{}' notifying blocked threads", thread.getName()); + } + released = true; + notifyAll(); + } } }
