Minor changes to Monitor to attempt to find a bug.

This commit is contained in:
wcrisman
2014-07-11 15:29:08 -07:00
parent 2b035e092c
commit 54b2f9b5ad

View File

@@ -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) {
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) {
Thread.currentThread().interrupt();
Debug.handle(e);
}//catch//
//If we couldn't get the lock in 60 seconds then display the stack of the
if(monitor.lockingThreadData == null) {
monitor.lockingThreadData = threadData;
result = true;
}//if//
else {
//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(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):");
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 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(0);
monitor.lock.wait();
}//try//
catch(InterruptedException e) {
Debug.log(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;
}//else//
}//if//
}//if//
else {
//Wait for <code>timeout</code> 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;