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;
|
result = true;
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
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) {
|
||||||
if(timeout == 0 && DEBUG) {
|
//Wait 10 minutes for the lock before reporting a possible deadlock.//
|
||||||
try {
|
if(DEBUG) {
|
||||||
monitor.lock.wait(600000);
|
try {
|
||||||
}//try//
|
monitor.lock.wait(600000);
|
||||||
catch(InterruptedException e) {
|
}//try//
|
||||||
Thread.currentThread().interrupt();
|
catch(InterruptedException e) {
|
||||||
}//catch//
|
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) {
|
if(monitor.lockingThreadData == null) {
|
||||||
|
Debug.log("MONITOR: Locking lock: " + Integer.toHexString(monitor.lock.hashCode()));
|
||||||
monitor.lockingThreadData = threadData;
|
monitor.lockingThreadData = threadData;
|
||||||
result = true;
|
result = true;
|
||||||
}//if//
|
}//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//
|
}//if//
|
||||||
else {
|
else {
|
||||||
|
//Wait for <code>timeout</code> milliseconds for the lock to become available before giving up.//
|
||||||
while((timeout > 0) && (monitor.lockingThreadData != null)) {
|
while((timeout > 0) && (monitor.lockingThreadData != null)) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
@@ -190,13 +197,14 @@ public static boolean lock(Monitor monitor, long timeout, boolean allowSuspend,
|
|||||||
monitor.lock.wait(timeout);
|
monitor.lock.wait(timeout);
|
||||||
}//try//
|
}//try//
|
||||||
catch(InterruptedException e) {
|
catch(InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Debug.handle(e);
|
||||||
}//catch//
|
}//catch//
|
||||||
|
|
||||||
timeout = timeout - (System.currentTimeMillis() - startTime);
|
timeout = timeout - (System.currentTimeMillis() - startTime);
|
||||||
}//while//
|
}//while//
|
||||||
|
|
||||||
if(monitor.lockingThreadData == null) {
|
if(monitor.lockingThreadData == null) {
|
||||||
|
Debug.log("MONITOR: Locking lock: " + Integer.toHexString(monitor.lock.hashCode()));
|
||||||
monitor.lockingThreadData = threadData;
|
monitor.lockingThreadData = threadData;
|
||||||
result = true;
|
result = true;
|
||||||
}//if//
|
}//if//
|
||||||
@@ -250,7 +258,7 @@ public static void unlock(Monitor monitor) {
|
|||||||
throw new SecurityException("Cannot unlock since the thread has no locks.");
|
throw new SecurityException("Cannot unlock since the thread has no locks.");
|
||||||
}//if//
|
}//if//
|
||||||
else if(threadData.currentLock != monitor) {
|
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.");
|
throw new SecurityException("Failed to unlock the monitor.");
|
||||||
}//else if//
|
}//else if//
|
||||||
|
|
||||||
@@ -265,9 +273,10 @@ public static void unlock(Monitor monitor) {
|
|||||||
|
|
||||||
//Reduce the lock count and clear the lock if zero.//
|
//Reduce the lock count and clear the lock if zero.//
|
||||||
if(--threadData.lockCount == 0) {
|
if(--threadData.lockCount == 0) {
|
||||||
synchronized(threadData.currentLock.lock) {
|
synchronized(monitor.lock) {
|
||||||
threadData.currentLock.lockingThreadData = null;
|
threadData.currentLock.lockingThreadData = null;
|
||||||
threadData.currentLock.lock.notify();
|
monitor.lock.notify();
|
||||||
|
Debug.log("MONITOR: Unlocking lock: " + Integer.toHexString(monitor.lock.hashCode()));
|
||||||
}//synchronized//
|
}//synchronized//
|
||||||
|
|
||||||
threadData.currentLock = null;
|
threadData.currentLock = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user