Minor changes to Monitor to attempt to find a bug.
This commit is contained in:
@@ -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 <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;
|
||||
|
||||
Reference in New Issue
Block a user