You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tr...@apache.org on 2007/10/19 07:41:13 UTC
svn commit: r586269 -
/mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFuture.java
Author: trustin
Date: Thu Oct 18 22:41:12 2007
New Revision: 586269
URL: http://svn.apache.org/viewvc?rev=586269&view=rev
Log:
Resolved issue: DIRMINA-456 (Provide mechanism for detecting a dead lock caused by calling IoFuture.await() in an I/O processor thread.)
* Improved DefaultIoFuture to check dead lock every five seconds. Checking the dead lock situation is an expensive operation. However, it shouldn't cost much in most cases because it's checked just every five seconds, which is eternity for computers.
Modified:
mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFuture.java
Modified: mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFuture.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFuture.java?rev=586269&r1=586268&r2=586269&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFuture.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFuture.java Thu Oct 18 22:41:12 2007
@@ -31,18 +31,15 @@
* @version $Rev$, $Date$
*/
public class DefaultIoFuture implements IoFuture {
+
+ private static final int DEAD_LOCK_CHECK_INTERVAL = 5000;
+
private final IoSession session;
-
private final Object lock;
-
private IoFutureListener firstListener;
-
private List<IoFutureListener> otherListeners;
-
private Object result;
-
private boolean ready;
-
private int waiters;
/**
@@ -72,7 +69,8 @@
while (!ready) {
waiters++;
try {
- lock.wait();
+ lock.wait(DEAD_LOCK_CHECK_INTERVAL);
+ checkDeadLock();
} finally {
waiters--;
}
@@ -87,17 +85,7 @@
}
public boolean await(long timeoutMillis) throws InterruptedException {
- synchronized (lock) {
- if (!ready) {
- waiters++;
- try {
- lock.wait(timeoutMillis);
- } finally {
- waiters--;
- }
- }
- return ready;
- }
+ return await0(timeoutMillis, true);
}
public IoFuture awaitUninterruptibly() {
@@ -105,10 +93,13 @@
while (!ready) {
waiters++;
try {
- lock.wait();
+ lock.wait(DEAD_LOCK_CHECK_INTERVAL);
} catch (InterruptedException e) {
} finally {
waiters--;
+ if (!ready) {
+ checkDeadLock();
+ }
}
}
}
@@ -121,6 +112,14 @@
}
public boolean awaitUninterruptibly(long timeoutMillis) {
+ try {
+ return await0(timeoutMillis, false);
+ } catch (InterruptedException e) {
+ throw new InternalError();
+ }
+ }
+
+ private boolean await0(long timeoutMillis, boolean interruptable) throws InterruptedException {
long startTime = timeoutMillis <= 0 ? 0 : System.currentTimeMillis();
long waitTime = timeoutMillis;
@@ -135,8 +134,11 @@
try {
for (;;) {
try {
- lock.wait(waitTime);
+ lock.wait(Math.min(waitTime, DEAD_LOCK_CHECK_INTERVAL));
} catch (InterruptedException e) {
+ if (interruptable) {
+ throw e;
+ }
}
if (ready) {
@@ -151,6 +153,28 @@
}
} finally {
waiters--;
+ if (!ready) {
+ checkDeadLock();
+ }
+ }
+ }
+ }
+
+ private void checkDeadLock() {
+ IllegalStateException e = new IllegalStateException(
+ "DEAD LOCK: " + IoFuture.class.getSimpleName() +
+ ".await() was invoked from an I/O processor thread. " +
+ "Please use " + IoFutureListener.class.getSimpleName() +
+ " or configure a proper thread model alternatively.");
+
+ for (StackTraceElement s: e.getStackTrace()) {
+ try {
+ Class<?> cls = DefaultIoFuture.class.getClassLoader().loadClass(s.getClassName());
+ if (IoProcessor.class.isAssignableFrom(cls)) {
+ throw e;
+ }
+ } catch (ClassNotFoundException cnfe) {
+ // Ignore
}
}
}