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/07/31 08:12:44 UTC

svn commit: r561238 - in /mina: branches/1.0/core/src/main/java/org/apache/mina/common/support/ branches/1.1/core/src/main/java/org/apache/mina/common/support/ trunk/core/src/main/java/org/apache/mina/common/support/

Author: trustin
Date: Mon Jul 30 23:12:43 2007
New Revision: 561238

URL: http://svn.apache.org/viewvc?view=rev&rev=561238
Log:
Fixed issue: DIRMINA-412 (WriteFuture.join() hangs when exception thrown in filterWrite)

Modified:
    mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
    mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
    mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
    mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
    mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
    mina/trunk/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java

Modified: mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: http://svn.apache.org/viewvc/mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java?view=diff&rev=561238&r1=561237&r2=561238
==============================================================================
--- mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java (original)
+++ mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java Mon Jul 30 23:12:43 2007
@@ -360,6 +360,7 @@
             entry.getFilter().filterWrite(entry.getNextFilter(), session,
                     writeRequest);
         } catch (Throwable e) {
+            writeRequest.getFuture().setWritten(false);
             fireExceptionCaught(session, e);
         }
     }

Modified: mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
URL: http://svn.apache.org/viewvc/mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java?view=diff&rev=561238&r1=561237&r2=561238
==============================================================================
--- mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java (original)
+++ mina/branches/1.0/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java Mon Jul 30 23:12:43 2007
@@ -1,203 +1,213 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.mina.common.support;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.mina.common.IoFuture;
-import org.apache.mina.common.IoFutureListener;
-import org.apache.mina.common.IoSession;
-
-/**
- * A default implementation of {@link IoFuture}.
- *  
- * @author The Apache Directory Project (mina-dev@directory.apache.org)
- * @version $Rev$, $Date$
- */
-public class DefaultIoFuture implements IoFuture {
-    private final IoSession session;
-
-    private final Object lock;
-
-    private IoFutureListener firstListener;
-
-    private List otherListeners;
-
-    private Object result;
-
-    private boolean ready;
-
-    /**
-     * Creates a new instance.
-     * 
-     * @param session an {@link IoSession} which is associated with this future
-     */
-    public DefaultIoFuture(IoSession session) {
-        this.session = session;
-        this.lock = this;
-    }
-
-    /**
-     * Creates a new instance which uses the specified object as a lock.
-     */
-    public DefaultIoFuture(IoSession session, Object lock) {
-        if (lock == null) {
-            throw new NullPointerException("lock");
-        }
-        this.session = session;
-        this.lock = lock;
-    }
-
-    public IoSession getSession() {
-        return session;
-    }
-
-    public Object getLock() {
-        return lock;
-    }
-
-    public void join() {
-        synchronized (lock) {
-            while (!ready) {
-                try {
-                    lock.wait();
-                } catch (InterruptedException e) {
-                }
-            }
-        }
-    }
-
-    public boolean join(long timeoutInMillis) {
-        long startTime = (timeoutInMillis <= 0) ? 0 : System
-                .currentTimeMillis();
-        long waitTime = timeoutInMillis;
-
-        synchronized (lock) {
-            if (ready) {
-                return ready;
-            } else if (waitTime <= 0) {
-                return ready;
-            }
-
-            for (;;) {
-                try {
-                    lock.wait(waitTime);
-                } catch (InterruptedException e) {
-                }
-
-                if (ready)
-                    return true;
-                else {
-                    waitTime = timeoutInMillis
-                            - (System.currentTimeMillis() - startTime);
-                    if (waitTime <= 0) {
-                        return ready;
-                    }
-                }
-            }
-        }
-    }
-
-    public boolean isReady() {
-        synchronized (lock) {
-            return ready;
-        }
-    }
-
-    /**
-     * Sets the result of the asynchronous operation, and mark it as finished.
-     */
-    protected void setValue(Object newValue) {
-        synchronized (lock) {
-            // Allow only once.
-            if (ready) {
-                return;
-            }
-
-            result = newValue;
-            ready = true;
-            lock.notifyAll();
-
-            notifyListeners();
-        }
-    }
-
-    /**
-     * Returns the result of the asynchronous operation.
-     */
-    protected Object getValue() {
-        synchronized (lock) {
-            return result;
-        }
-    }
-
-    public void addListener(IoFutureListener listener) {
-        if (listener == null) {
-            throw new NullPointerException("listener");
-        }
-
-        synchronized (lock) {
-            if (firstListener == null) {
-                firstListener = listener;
-            } else {
-                if (otherListeners == null) {
-                    otherListeners = new ArrayList(1);
-                }
-                otherListeners.add(listener);
-            }
-            if (ready) {
-                listener.operationComplete(this);
-            }
-        }
-    }
-
-    public void removeListener(IoFutureListener listener) {
-        if (listener == null) {
-            throw new NullPointerException("listener");
-        }
-
-        synchronized (lock) {
-            if (listener == firstListener) {
-                if (otherListeners != null && !otherListeners.isEmpty()) {
-                    firstListener = (IoFutureListener) otherListeners.remove(0);
-                } else {
-                    firstListener = null;
-                }
-            } else if (otherListeners != null) {
-                otherListeners.remove(listener);
-            }
-        }
-    }
-
-    private void notifyListeners() {
-        synchronized (lock) {
-            if (firstListener != null) {
-                firstListener.operationComplete(this);
-                if (otherListeners != null) {
-                    for (Iterator i = otherListeners.iterator(); i.hasNext();) {
-                        ((IoFutureListener) i.next()).operationComplete(this);
-                    }
-                }
-            }
-        }
-    }
-}
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.mina.common.support;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoFuture;
+import org.apache.mina.common.IoFutureListener;
+import org.apache.mina.common.IoSession;
+
+/**
+ * A default implementation of {@link IoFuture}.
+ *  
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev$, $Date$
+ */
+public class DefaultIoFuture implements IoFuture {
+    private final IoSession session;
+
+    private final Object lock;
+
+    private IoFutureListener firstListener;
+
+    private List otherListeners;
+
+    private Object result;
+
+    private boolean ready;
+
+    /**
+     * Creates a new instance.
+     * 
+     * @param session an {@link IoSession} which is associated with this future
+     */
+    public DefaultIoFuture(IoSession session) {
+        this.session = session;
+        this.lock = this;
+    }
+
+    /**
+     * Creates a new instance which uses the specified object as a lock.
+     */
+    public DefaultIoFuture(IoSession session, Object lock) {
+        if (lock == null) {
+            throw new NullPointerException("lock");
+        }
+        this.session = session;
+        this.lock = lock;
+    }
+
+    public IoSession getSession() {
+        return session;
+    }
+
+    public Object getLock() {
+        return lock;
+    }
+
+    public void join() {
+        synchronized (lock) {
+            while (!ready) {
+                try {
+                    lock.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    public boolean join(long timeoutInMillis) {
+        long startTime = (timeoutInMillis <= 0) ? 0 : System
+                .currentTimeMillis();
+        long waitTime = timeoutInMillis;
+
+        synchronized (lock) {
+            if (ready) {
+                return ready;
+            } else if (waitTime <= 0) {
+                return ready;
+            }
+
+            for (;;) {
+                try {
+                    lock.wait(waitTime);
+                } catch (InterruptedException e) {
+                }
+
+                if (ready)
+                    return true;
+                else {
+                    waitTime = timeoutInMillis
+                            - (System.currentTimeMillis() - startTime);
+                    if (waitTime <= 0) {
+                        return ready;
+                    }
+                }
+            }
+        }
+    }
+
+    public boolean isReady() {
+        synchronized (lock) {
+            return ready;
+        }
+    }
+
+    /**
+     * Sets the result of the asynchronous operation, and mark it as finished.
+     */
+    protected void setValue(Object newValue) {
+        synchronized (lock) {
+            // Allow only once.
+            if (ready) {
+                return;
+            }
+
+            result = newValue;
+            ready = true;
+            lock.notifyAll();
+
+            notifyListeners();
+        }
+    }
+
+    /**
+     * Returns the result of the asynchronous operation.
+     */
+    protected Object getValue() {
+        synchronized (lock) {
+            return result;
+        }
+    }
+
+    public void addListener(IoFutureListener listener) {
+        if (listener == null) {
+            throw new NullPointerException("listener");
+        }
+
+        synchronized (lock) {
+            if (!ready) {
+                if (firstListener == null) {
+                    firstListener = listener;
+                } else {
+                    if (otherListeners == null) {
+                        otherListeners = new ArrayList(1);
+                    }
+                    otherListeners.add(listener);
+                }
+            } else {
+                notifyListener(listener);
+            }
+        }
+    }
+
+    public void removeListener(IoFutureListener listener) {
+        if (listener == null) {
+            throw new NullPointerException("listener");
+        }
+
+        synchronized (lock) {
+            if (listener == firstListener) {
+                if (otherListeners != null && !otherListeners.isEmpty()) {
+                    firstListener = (IoFutureListener) otherListeners.remove(0);
+                } else {
+                    firstListener = null;
+                }
+            } else if (otherListeners != null) {
+                otherListeners.remove(listener);
+            }
+        }
+    }
+
+    private void notifyListeners() {
+        synchronized (lock) {
+            if (firstListener != null) {
+                notifyListener(firstListener);
+                if (otherListeners != null) {
+                    for (Iterator i = otherListeners.iterator(); i.hasNext();) {
+                        notifyListener((IoFutureListener) i.next());
+                    }
+                }
+            }
+        }
+    }
+
+    private void notifyListener(IoFutureListener l) {
+        try {
+            l.operationComplete(this);
+        } catch (Throwable t) {
+            ExceptionMonitor.getInstance().exceptionCaught(t);
+        }
+    }
+}

Modified: mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: http://svn.apache.org/viewvc/mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java?view=diff&rev=561238&r1=561237&r2=561238
==============================================================================
--- mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java (original)
+++ mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java Mon Jul 30 23:12:43 2007
@@ -361,6 +361,7 @@
             entry.getFilter().filterWrite(entry.getNextFilter(), session,
                     writeRequest);
         } catch (Throwable e) {
+            writeRequest.getFuture().setWritten(false);
             fireExceptionCaught(session, e);
         }
     }

Modified: mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
URL: http://svn.apache.org/viewvc/mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java?view=diff&rev=561238&r1=561237&r2=561238
==============================================================================
--- mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java (original)
+++ mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java Mon Jul 30 23:12:43 2007
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.mina.common.ExceptionMonitor;
 import org.apache.mina.common.IoFuture;
 import org.apache.mina.common.IoFutureListener;
 import org.apache.mina.common.IoSession;
@@ -139,16 +140,17 @@
         }
 
         synchronized (lock) {
-            if (firstListener == null) {
-                firstListener = listener;
-            } else {
-                if (otherListeners == null) {
-                    otherListeners = new ArrayList<IoFutureListener>(1);
+            if (!ready) {
+                if (firstListener == null) {
+                    firstListener = listener;
+                } else {
+                    if (otherListeners == null) {
+                        otherListeners = new ArrayList<IoFutureListener>(1);
+                    }
+                    otherListeners.add(listener);
                 }
-                otherListeners.add(listener);
-            }
-            if (ready) {
-                listener.operationComplete(this);
+            } else {
+                notifyListener(listener);
             }
         }
     }
@@ -174,13 +176,21 @@
     private void notifyListeners() {
         synchronized (lock) {
             if (firstListener != null) {
-                firstListener.operationComplete(this);
+                notifyListener(firstListener);
                 if (otherListeners != null) {
                     for (IoFutureListener l : otherListeners) {
-                        l.operationComplete(this);
+                        notifyListener(l);
                     }
                 }
             }
+        }
+    }
+    
+    private void notifyListener(IoFutureListener l) {
+        try {
+            l.operationComplete(this);
+        } catch (Throwable t) {
+            ExceptionMonitor.getInstance().exceptionCaught(t);
         }
     }
 }

Modified: mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java?view=diff&rev=561238&r1=561237&r2=561238
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java Mon Jul 30 23:12:43 2007
@@ -393,6 +393,7 @@
             entry.getFilter().filterWrite(entry.getNextFilter(), session,
                     writeRequest);
         } catch (Throwable e) {
+            writeRequest.getFuture().setWritten(false);
             fireExceptionCaught(session, e);
         }
     }

Modified: mina/trunk/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java?view=diff&rev=561238&r1=561237&r2=561238
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java Mon Jul 30 23:12:43 2007
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.mina.common.ExceptionMonitor;
 import org.apache.mina.common.IoFuture;
 import org.apache.mina.common.IoFutureListener;
 import org.apache.mina.common.IoSession;
@@ -215,7 +216,7 @@
         }
 
         if (notifyNow) {
-            listener.operationComplete(this);
+            notifyListener(listener);
         }
         return this;
     }
@@ -247,15 +248,23 @@
         // because 'ready' flag will be checked against both addListener and
         // removeListener calls.
         if (firstListener != null) {
-            firstListener.operationComplete(this);
+            notifyListener(firstListener);
             firstListener = null;
 
             if (otherListeners != null) {
                 for (IoFutureListener l : otherListeners) {
-                    l.operationComplete(this);
+                    notifyListener(l);
                 }
                 otherListeners = null;
             }
+        }
+    }
+    
+    private void notifyListener(IoFutureListener l) {
+        try {
+            l.operationComplete(this);
+        } catch (Throwable t) {
+            ExceptionMonitor.getInstance().exceptionCaught(t);
         }
     }
 }