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();
+               }
        }
 }

Reply via email to