From 54b2f9b5ad189d8cd8c8509a618bdf89c4b80d8b Mon Sep 17 00:00:00 2001 From: wcrisman Date: Fri, 11 Jul 2014 15:29:08 -0700 Subject: [PATCH] Minor changes to Monitor to attempt to find a bug. --- Common/src/com/common/thread/Monitor.java | 77 +++++++++++++---------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/Common/src/com/common/thread/Monitor.java b/Common/src/com/common/thread/Monitor.java index 429fcbf..880742c 100644 --- a/Common/src/com/common/thread/Monitor.java +++ b/Common/src/com/common/thread/Monitor.java @@ -146,43 +146,50 @@ public static boolean lock(Monitor monitor, long timeout, boolean allowSuspend, result = true; }//if// else { - //If we have debugging on then we should try to detect deadlocks and report the stack of the last locking thread.// - if(timeout == 0 && DEBUG) { - try { - monitor.lock.wait(600000); - }//try// - catch(InterruptedException e) { - Thread.currentThread().interrupt(); - }//catch// + if(timeout == 0) { + //Wait 10 minutes for the lock before reporting a possible deadlock.// + if(DEBUG) { + try { + monitor.lock.wait(600000); + }//try// + catch(InterruptedException e) { + Debug.handle(e); + }//catch// + + //If we got the lock then proceed, otherwise report a possible deadlock and then continue waiting.// + if(monitor.lockingThreadData != null) { + Throwable stack = monitor.lockingThreadData.stack; + + //Note: This access to stack is a bit unsafe, but should be fine since stack is immutable.// + if(stack != null) { + Debug.log("Possible deadlock detected while attempting to obtain a lock. Last locking thread's stack follows (RuntimeException):", stack); + Debug.log("Lock attempt stack (RuntimeException):", new RuntimeException()); + }//if// + }//if// + }//if// - //If we couldn't get the lock in 60 seconds then display the stack of the + //If we haven't got the lock yet, then wait indefinately.// + if(monitor.lockingThreadData != null) { + //Wait indefinately for the lock to become available.// + while(monitor.lockingThreadData != null) { + try { + monitor.lock.wait(); + }//try// + catch(InterruptedException e) { + Debug.handle(e); + }//catch// + }//while// + }//if// + + //If we got the lock then proceed, otherwise we couldn't get the lock in 10 minutes of waiting... if(monitor.lockingThreadData == null) { + Debug.log("MONITOR: Locking lock: " + Integer.toHexString(monitor.lock.hashCode())); monitor.lockingThreadData = threadData; result = true; }//if// - else { - Throwable stack = monitor.lockingThreadData.stack; - - //Note: This access to stack is a bit unsafe, but should be fine since stack is immutable.// - if(stack != null) { - Debug.log(stack, "Possible deadlock detected while attempting to obtain a lock. Last locking thread's stack follows (RuntimeException):"); - Debug.log(new RuntimeException(), "Lock attempt stack (RuntimeException):"); - }//if// - - while(monitor.lockingThreadData != null) { - try { - monitor.lock.wait(0); - }//try// - catch(InterruptedException e) { - Debug.log(e); - }//catch// - }//while// - - monitor.lockingThreadData = threadData; - result = true; - }//else// }//if// else { + //Wait for timeout milliseconds for the lock to become available before giving up.// while((timeout > 0) && (monitor.lockingThreadData != null)) { long startTime = System.currentTimeMillis(); @@ -190,13 +197,14 @@ public static boolean lock(Monitor monitor, long timeout, boolean allowSuspend, monitor.lock.wait(timeout); }//try// catch(InterruptedException e) { - Thread.currentThread().interrupt(); + Debug.handle(e); }//catch// timeout = timeout - (System.currentTimeMillis() - startTime); }//while// if(monitor.lockingThreadData == null) { + Debug.log("MONITOR: Locking lock: " + Integer.toHexString(monitor.lock.hashCode())); monitor.lockingThreadData = threadData; result = true; }//if// @@ -250,7 +258,7 @@ public static void unlock(Monitor monitor) { throw new SecurityException("Cannot unlock since the thread has no locks."); }//if// else if(threadData.currentLock != monitor) { - Debug.log(threadData.stack, "Cannot unlock the monitor since it is not the currently locked monitor. The following stack (runtime-exception) shows the thread obtaining the currently held lock."); + Debug.log("Cannot unlock the monitor since it is not the currently locked monitor. The following stack (runtime-exception) shows the thread obtaining the currently held lock.", threadData.stack); throw new SecurityException("Failed to unlock the monitor."); }//else if// @@ -265,9 +273,10 @@ public static void unlock(Monitor monitor) { //Reduce the lock count and clear the lock if zero.// if(--threadData.lockCount == 0) { - synchronized(threadData.currentLock.lock) { + synchronized(monitor.lock) { threadData.currentLock.lockingThreadData = null; - threadData.currentLock.lock.notify(); + monitor.lock.notify(); + Debug.log("MONITOR: Unlocking lock: " + Integer.toHexString(monitor.lock.hashCode())); }//synchronized// threadData.currentLock = null;