Author: trustin
Date: Sun Sep 30 04:34:06 2007
New Revision: 580695

URL: http://svn.apache.org/viewvc?rev=580695&view=rev
Log:
Resolved issue: DIRMINA-382 (Provide a close() method that doesn't close the 
connection until all messages are written.)
* Added IoSession.close(boolean) and closeOnFlush()
** Default implementation in AbstractIoSession
*** closeOnFlush queues a fake WriteRequest.  When it's polled, 
IoSession.close() is automatically called, and the queue is cleared.


Modified:
    mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java
    mina/trunk/core/src/main/java/org/apache/mina/common/IoSession.java

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java?rev=580695&r1=580694&r2=580695&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java 
Sun Sep 30 04:34:06 2007
@@ -51,7 +51,14 @@
                 s.scheduledWriteBytes.set(0);
                 s.scheduledWriteMessages.set(0);
             }
-        };
+    };
+
+    /**
+     * An internal write request object that triggers session close.
+     * @see #writeRequestQueue
+     */
+    private static final WriteRequest CLOSE_REQUEST =
+        new DefaultWriteRequest(new Object());
 
     private final Object lock = new Object();
 
@@ -59,7 +66,32 @@
             .synchronizedMap(new HashMap<Object, Object>(4));
 
     private final Queue<WriteRequest> writeRequestQueue =
-        new ConcurrentLinkedQueue<WriteRequest>();
+        new ConcurrentLinkedQueue<WriteRequest>() {
+            private static final long serialVersionUID = -3899506857975733565L;
+
+            // Discard close request offered by closeOnFlush() silently.
+            @Override
+            public WriteRequest peek() {
+                WriteRequest answer = super.peek();
+                if (answer == CLOSE_REQUEST) {
+                    AbstractIoSession.this.close();
+                    clear();
+                    answer = null;
+                }
+                return answer;
+            }
+
+            @Override
+            public WriteRequest poll() {
+                WriteRequest answer = super.poll();
+                if (answer == CLOSE_REQUEST) {
+                    AbstractIoSession.this.close();
+                    clear();
+                    answer = null;
+                }
+                return answer;
+            }
+    };
 
     private final long creationTime;
 
@@ -136,6 +168,14 @@
             return true;
         }
     }
+    
+    public CloseFuture close(boolean rightNow) {
+        if (rightNow) {
+            return close();
+        } else {
+            return closeOnFlush();
+        }
+    }
 
     public CloseFuture close() {
         synchronized (lock) {
@@ -147,6 +187,11 @@
         }
 
         getFilterChain().fireFilterClose();
+        return closeFuture;
+    }
+    
+    public CloseFuture closeOnFlush() {
+        getWriteRequestQueue().offer(CLOSE_REQUEST);
         return closeFuture;
     }
 

Modified: mina/trunk/core/src/main/java/org/apache/mina/common/IoSession.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/IoSession.java?rev=580695&r1=580694&r2=580695&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/IoSession.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/IoSession.java Sun Sep 
30 04:34:06 2007
@@ -116,6 +116,25 @@
      * the session actually closed.
      */
     CloseFuture close();
+    
+    /**
+     * Closes this session after all queued write requests are flushed.
+     * This operation is asynchronous.  Wait for the returned [EMAIL 
PROTECTED] CloseFuture}
+     * if you want to wait for the session actually closed.
+     */
+    CloseFuture closeOnFlush();
+    
+    /**
+     * Closes this session immediately or after all queued write requests
+     * are flushed.  This operation is asynchronous.  Wait for the returned
+     * [EMAIL PROTECTED] CloseFuture} if you want to wait for the session 
actually closed.
+     * 
+     * @param immediately [EMAIL PROTECTED] true} to close this session 
immediately
+     *                    (i.e. [EMAIL PROTECTED] #close()}).
+     *                    [EMAIL PROTECTED] false} to close this session after 
all queued
+     *                    write requests are flushed (i.e. [EMAIL PROTECTED] 
#closeOnFlush()}).
+     */
+    CloseFuture close(boolean immediately);
 
     /**
      * Returns an attachment of this session.


Reply via email to