You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2005/09/06 12:41:09 UTC

svn commit: r278969 - in /directory/network: branches/0.7/ branches/0.7/src/examples/org/apache/mina/examples/echoserver/ branches/0.7/src/java/org/apache/mina/common/ branches/0.7/src/java/org/apache/mina/io/socket/ branches/0.7/src/java/org/apache/mi...

Author: trustin
Date: Tue Sep  6 03:40:49 2005
New Revision: 278969

URL: http://svn.apache.org/viewcvs?rev=278969&view=rev
Log:
Related issues:
* DIRMINA-82 - IdleSession reported only once per IO
* DIRMINA-87 - Session.getCreationTime()
* DIRMINA-86 - There's no way to reset idle status of the session other than performing I/O.

Changes:
* Added Session.getCreationTime()
* Added Session.getLastIdleTime(), Session.getIdleCount()
* Now sessionIdle events are fired periodically.


Modified:
    directory/network/branches/0.7/project.xml
    directory/network/branches/0.7/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java
    directory/network/branches/0.7/src/java/org/apache/mina/common/BaseSession.java
    directory/network/branches/0.7/src/java/org/apache/mina/common/Session.java
    directory/network/branches/0.7/src/java/org/apache/mina/io/socket/SocketIoProcessor.java
    directory/network/branches/0.7/src/java/org/apache/mina/protocol/io/IoProtocolSession.java
    directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeFilter.java
    directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeIdleStatusChecker.java
    directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java
    directory/network/trunk/src/java/org/apache/mina/common/BaseIoSession.java
    directory/network/trunk/src/java/org/apache/mina/common/IoSession.java
    directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/SocketIoProcessor.java
    directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeFilter.java
    directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeIdleStatusChecker.java

Modified: directory/network/branches/0.7/project.xml
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/project.xml?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/project.xml (original)
+++ directory/network/branches/0.7/project.xml Tue Sep  6 03:40:49 2005
@@ -5,7 +5,7 @@
   <id>mina</id>
   <name>MINA</name>
   <package>org.apache.mina</package>
-  <currentVersion>0.7.5-SNAPSHOT</currentVersion>
+  <currentVersion>0.8.0-SNAPSHOT</currentVersion>
   <inceptionYear>2004</inceptionYear>
 
   <logo>http://directory.apache.org/images/apache-directory-logo.png</logo>

Modified: directory/network/branches/0.7/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java (original)
+++ directory/network/branches/0.7/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java Tue Sep  6 03:40:49 2005
@@ -18,7 +18,10 @@
  */
 package org.apache.mina.examples.echoserver;
 
+import java.util.logging.Logger;
+
 import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IdleStatus;
 import org.apache.mina.common.SessionConfig;
 import org.apache.mina.io.IoHandler;
 import org.apache.mina.io.IoHandlerAdapter;
@@ -33,6 +36,8 @@
  */
 public class EchoProtocolHandler extends IoHandlerAdapter
 {
+    private static final Logger log = Logger.getLogger( EchoProtocolHandler.class.getName() );
+
     public void sessionCreated( IoSession session )
     {
         SessionConfig cfg = session.getConfig();
@@ -40,6 +45,16 @@
         {
             ( ( SocketSessionConfig ) cfg ).setSessionReceiveBufferSize( 2048 );
         }
+        
+        cfg.setIdleTime( IdleStatus.BOTH_IDLE, 10 );
+    }
+
+    public void sessionIdle( IoSession session, IdleStatus status )
+    {
+        log.info(
+                "*** IDLE #" +
+                session.getIdleCount( IdleStatus.BOTH_IDLE ) +
+                " ***" );
     }
 
     public void exceptionCaught( IoSession session, Throwable cause )

Modified: directory/network/branches/0.7/src/java/org/apache/mina/common/BaseSession.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/common/BaseSession.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/common/BaseSession.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/common/BaseSession.java Tue Sep  6 03:40:49 2005
@@ -34,6 +34,7 @@
 public abstract class BaseSession implements Session
 {
     private final Map attributes = new HashMap();
+    private final long creationTime;
 
     private long readBytes;
     private long writtenBytes;
@@ -42,14 +43,19 @@
     private long lastReadTime;
     private long lastWriteTime;
 
-    private boolean idleForBoth;
-    private boolean idleForRead;
-    private boolean idleForWrite;
-
+    private int idleCountForBoth;
+    private int idleCountForRead;
+    private int idleCountForWrite;
+    
+    private long lastIdleTimeForBoth;
+    private long lastIdleTimeForRead;
+    private long lastIdleTimeForWrite;
 
     protected BaseSession()
     {
-        lastReadTime = lastWriteTime = System.currentTimeMillis();
+        creationTime = lastReadTime = lastWriteTime =
+            lastIdleTimeForBoth = lastIdleTimeForRead = lastIdleTimeForWrite =
+                System.currentTimeMillis();
     }
     
     public void close()
@@ -129,6 +135,11 @@
     {
         writtenWriteRequests ++;
     }
+    
+    public long getCreationTime()
+    {
+        return creationTime;
+    }
 
     public long getLastIoTime()
     {
@@ -148,25 +159,75 @@
     public boolean isIdle( IdleStatus status )
     {
         if( status == IdleStatus.BOTH_IDLE )
-            return idleForBoth;
+            return idleCountForBoth > 0;
 
         if( status == IdleStatus.READER_IDLE )
-            return idleForRead;
+            return idleCountForRead > 0;
 
         if( status == IdleStatus.WRITER_IDLE )
-            return idleForWrite;
+            return idleCountForWrite > 0;
 
         throw new IllegalArgumentException( "Unknown idle status: " + status );
     }
 
-    public void setIdle( IdleStatus status, boolean value )
+    public int getIdleCount( IdleStatus status )
+    {
+        if( status == IdleStatus.BOTH_IDLE )
+            return idleCountForBoth;
+
+        if( status == IdleStatus.READER_IDLE )
+            return idleCountForRead;
+
+        if( status == IdleStatus.WRITER_IDLE )
+            return idleCountForWrite;
+
+        throw new IllegalArgumentException( "Unknown idle status: " + status );
+    }
+    
+    public long getLastIdleTime( IdleStatus status )
+    {
+        if( status == IdleStatus.BOTH_IDLE )
+            return lastIdleTimeForBoth;
+
+        if( status == IdleStatus.READER_IDLE )
+            return lastIdleTimeForRead;
+
+        if( status == IdleStatus.WRITER_IDLE )
+            return lastIdleTimeForWrite;
+
+        throw new IllegalArgumentException( "Unknown idle status: " + status );
+    }
+
+    public void increaseIdleCount( IdleStatus status )
+    {
+        if( status == IdleStatus.BOTH_IDLE )
+        {
+            idleCountForBoth ++;
+            lastIdleTimeForBoth = System.currentTimeMillis();
+        }
+        else if( status == IdleStatus.READER_IDLE )
+        {
+            idleCountForRead ++;
+            lastIdleTimeForRead = System.currentTimeMillis();
+        }
+        else if( status == IdleStatus.WRITER_IDLE )
+        {
+            idleCountForWrite ++;
+            lastIdleTimeForWrite = System.currentTimeMillis();
+        }
+        else
+            throw new IllegalArgumentException( "Unknown idle status: "
+                                                + status );
+    }
+
+    public void resetIdleCount( IdleStatus status )
     {
         if( status == IdleStatus.BOTH_IDLE )
-            idleForBoth = value;
+            idleCountForBoth = 0;
         else if( status == IdleStatus.READER_IDLE )
-            idleForRead = value;
+            idleCountForRead = 0;
         else if( status == IdleStatus.WRITER_IDLE )
-            idleForWrite = value;
+            idleCountForWrite = 0;
         else
             throw new IllegalArgumentException( "Unknown idle status: "
                                                 + status );

Modified: directory/network/branches/0.7/src/java/org/apache/mina/common/Session.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/common/Session.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/common/Session.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/common/Session.java Tue Sep  6 03:40:49 2005
@@ -140,6 +140,11 @@
     int getScheduledWriteRequests();
 
     /**
+     * Returns the time in millis when this session is created.
+     */
+    long getCreationTime();
+    
+    /**
      * Returns the time in millis when I/O occurred lastly.
      */
     long getLastIoTime();
@@ -159,4 +164,22 @@
      * {@link IdleStatus}.
      */
     boolean isIdle( IdleStatus status );
+
+    /**
+     * Returns the number of the fired continuous <tt>sessionIdle</tt> events
+     * for the specified {@link IdleStatus}.
+     * <p>
+     * If <tt>sessionIdle</tt> event is fired first after some time after I/O,
+     * <tt>idleCount</tt> becomes <tt>1</tt>.  <tt>idleCount</tt> resets to
+     * <tt>0</tt> if any I/O occurs again, otherwise it increases to
+     * <tt>2</tt> and so on if <tt>sessionIdle</tt> event is fired again without
+     * any I/O between two (or more) <tt>sessionIdle</tt> events.
+     */
+    int getIdleCount( IdleStatus status );
+    
+    /**
+     * Returns the time in millis when the last <tt>sessionIdle</tt> event
+     * is fired for the specified {@link IdleStatus}.
+     */
+    long getLastIdleTime( IdleStatus status );
 }

Modified: directory/network/branches/0.7/src/java/org/apache/mina/io/socket/SocketIoProcessor.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/io/socket/SocketIoProcessor.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/io/socket/SocketIoProcessor.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/io/socket/SocketIoProcessor.java Tue Sep  6 03:40:49 2005
@@ -273,8 +273,8 @@
             }
 
             session.increaseReadBytes( readBytes );
-            session.setIdle( IdleStatus.BOTH_IDLE, false );
-            session.setIdle( IdleStatus.READER_IDLE, false );
+            session.resetIdleCount( IdleStatus.BOTH_IDLE );
+            session.resetIdleCount( IdleStatus.READER_IDLE );
 
             if( readBytes > 0 )
             {
@@ -344,15 +344,21 @@
     {
         SessionConfig config = session.getConfig();
 
-        notifyIdleSession0( session, currentTime, config
-                .getIdleTimeInMillis( IdleStatus.BOTH_IDLE ),
-                            IdleStatus.BOTH_IDLE, session.getLastIoTime() );
-        notifyIdleSession0( session, currentTime, config
-                .getIdleTimeInMillis( IdleStatus.READER_IDLE ),
-                            IdleStatus.READER_IDLE, session.getLastReadTime() );
-        notifyIdleSession0( session, currentTime, config
-                .getIdleTimeInMillis( IdleStatus.WRITER_IDLE ),
-                            IdleStatus.WRITER_IDLE, session.getLastWriteTime() );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.BOTH_IDLE ),
+                IdleStatus.BOTH_IDLE,
+                Math.max( session.getLastIoTime(), session.getLastIdleTime( IdleStatus.BOTH_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.READER_IDLE ),
+                IdleStatus.READER_IDLE,
+                Math.max( session.getLastReadTime(), session.getLastIdleTime( IdleStatus.READER_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.WRITER_IDLE ),
+                IdleStatus.WRITER_IDLE,
+                Math.max( session.getLastWriteTime(), session.getLastIdleTime( IdleStatus.WRITER_IDLE ) ) );
 
         notifyWriteTimeoutSession( session, currentTime, config
                 .getWriteTimeoutInMillis(), session.getLastWriteTime() );
@@ -362,10 +368,10 @@
                                     long idleTime, IdleStatus status,
                                     long lastIoTime )
     {
-        if( idleTime > 0 && !session.isIdle( status ) && lastIoTime != 0
+        if( idleTime > 0 && lastIoTime != 0
             && ( currentTime - lastIoTime ) >= idleTime )
         {
-            session.setIdle( status, true );
+            session.increaseIdleCount( status );
             session.getManagerFilterChain().sessionIdle( session, status );
         }
     }
@@ -506,8 +512,8 @@
                 if( writtenBytes > 0 )
                 {
                     session.increaseWrittenBytes( writtenBytes );
-                    session.setIdle( IdleStatus.BOTH_IDLE, false );
-                    session.setIdle( IdleStatus.WRITER_IDLE, false );
+                    session.resetIdleCount( IdleStatus.BOTH_IDLE );
+                    session.resetIdleCount( IdleStatus.WRITER_IDLE );
                 }
 
                 SelectionKey key = session.getSelectionKey();

Modified: directory/network/branches/0.7/src/java/org/apache/mina/protocol/io/IoProtocolSession.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/protocol/io/IoProtocolSession.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/protocol/io/IoProtocolSession.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/protocol/io/IoProtocolSession.java Tue Sep  6 03:40:49 2005
@@ -176,6 +176,11 @@
         return session.getWrittenBytes();
     }
 
+    public long getCreationTime()
+    {
+        return session.getCreationTime();
+    }
+
     public long getLastIoTime()
     {
         return session.getLastIoTime();
@@ -194,5 +199,15 @@
     public boolean isIdle( IdleStatus status )
     {
         return session.isIdle( status );
+    }
+
+    public int getIdleCount( IdleStatus status )
+    {
+        return session.getIdleCount( status );
+    }
+
+    public long getLastIdleTime( IdleStatus status )
+    {
+        return session.getLastIdleTime( status );
     }
 }

Modified: directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeFilter.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeFilter.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeFilter.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeFilter.java Tue Sep  6 03:40:49 2005
@@ -20,8 +20,8 @@
     {
         VmPipeSession vps = ( VmPipeSession ) session;
 
-        vps.setIdle( IdleStatus.BOTH_IDLE, false );
-        vps.setIdle( IdleStatus.READER_IDLE, false );
+        vps.resetIdleCount( IdleStatus.BOTH_IDLE );
+        vps.resetIdleCount( IdleStatus.READER_IDLE );
         vps.increaseReadBytes( 1 );
 
         // fire messageSent event first
@@ -35,8 +35,8 @@
                             ProtocolSession session, Object message )
     {
         VmPipeSession vps = ( VmPipeSession ) session;
-        vps.setIdle( IdleStatus.BOTH_IDLE, false );
-        vps.setIdle( IdleStatus.WRITER_IDLE, false );
+        vps.resetIdleCount( IdleStatus.BOTH_IDLE );
+        vps.resetIdleCount( IdleStatus.WRITER_IDLE );
         vps.increaseWrittenBytes( 1 );
         vps.increaseWrittenWriteRequests();
 

Modified: directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeIdleStatusChecker.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeIdleStatusChecker.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeIdleStatusChecker.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/protocol/vmpipe/VmPipeIdleStatusChecker.java Tue Sep  6 03:40:49 2005
@@ -71,51 +71,45 @@
                         }
                         else
                         {
-                            long idleTime;
-                            SessionConfig config = session.getConfig();
-
-                            if( !session.isIdle( IdleStatus.BOTH_IDLE ) )
-                            {
-                                idleTime = config
-                                        .getIdleTimeInMillis( IdleStatus.BOTH_IDLE );
-                                session.setIdle( IdleStatus.BOTH_IDLE,
-                                                 idleTime > 0L
-                                                 && ( currentTime - session.getLastIoTime() ) > idleTime );
-                                if( session.isIdle( IdleStatus.BOTH_IDLE ) )
-                                    session.getManagerFilterChain()
-                                            .sessionIdle( session,
-                                                          IdleStatus.BOTH_IDLE );
-                            }
-
-                            if( !session.isIdle( IdleStatus.READER_IDLE ) )
-                            {
-                                idleTime = config
-                                        .getIdleTimeInMillis( IdleStatus.READER_IDLE );
-                                session.setIdle( IdleStatus.READER_IDLE,
-                                                 idleTime > 0L
-                                                 && ( currentTime - session.getLastReadTime() ) > idleTime );
-                                if( session.isIdle( IdleStatus.READER_IDLE ) )
-                                    session.getManagerFilterChain()
-                                            .sessionIdle( session,
-                                                          IdleStatus.READER_IDLE );
-                            }
-
-                            if( !session.isIdle( IdleStatus.WRITER_IDLE ) )
-                            {
-                                idleTime = config
-                                        .getIdleTimeInMillis( IdleStatus.WRITER_IDLE );
-                                session.setIdle( IdleStatus.WRITER_IDLE,
-                                                 idleTime > 0L
-                                                 && ( currentTime - session.getLastWriteTime() ) > idleTime );
-                                if( session.isIdle( IdleStatus.WRITER_IDLE ) )
-                                    session.getManagerFilterChain()
-                                            .sessionIdle( session,
-                                                          IdleStatus.WRITER_IDLE );
-                            }
+                            notifyIdleSession( session, currentTime );
                         }
                     }
                 }
             }
         }
     }
+    
+    private void notifyIdleSession( VmPipeSession session, long currentTime )
+    {
+        SessionConfig config = session.getConfig();
+
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.BOTH_IDLE ),
+                IdleStatus.BOTH_IDLE,
+                Math.max( session.getLastIoTime(), session.getLastIdleTime( IdleStatus.BOTH_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.READER_IDLE ),
+                IdleStatus.READER_IDLE,
+                Math.max( session.getLastReadTime(), session.getLastIdleTime( IdleStatus.READER_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.WRITER_IDLE ),
+                IdleStatus.WRITER_IDLE,
+                Math.max( session.getLastWriteTime(), session.getLastIdleTime( IdleStatus.WRITER_IDLE ) ) );
+    }
+
+    private void notifyIdleSession0( VmPipeSession session, long currentTime,
+                                    long idleTime, IdleStatus status,
+                                    long lastIoTime )
+    {
+        if( idleTime > 0 && lastIoTime != 0
+            && ( currentTime - lastIoTime ) >= idleTime )
+        {
+            session.increaseIdleCount( status );
+            session.getManagerFilterChain().sessionIdle( session, status );
+        }
+    }
+
 }

Modified: directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java (original)
+++ directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java Tue Sep  6 03:40:49 2005
@@ -18,7 +18,10 @@
  */
 package org.apache.mina.examples.echoserver;
 
+import java.util.logging.Logger;
+
 import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IdleStatus;
 import org.apache.mina.common.IoHandler;
 import org.apache.mina.common.IoHandlerAdapter;
 import org.apache.mina.common.IoSession;
@@ -33,6 +36,8 @@
  */
 public class EchoProtocolHandler extends IoHandlerAdapter
 {
+    private static final Logger log = Logger.getLogger( EchoProtocolHandler.class.getName() );
+
     public void sessionCreated( IoSession session )
     {
         IoSessionConfig cfg = session.getConfig();
@@ -40,6 +45,16 @@
         {
             ( ( SocketSessionConfig ) cfg ).setSessionReceiveBufferSize( 2048 );
         }
+        
+        cfg.setIdleTime( IdleStatus.BOTH_IDLE, 10 );
+    }
+    
+    public void sessionIdle( IoSession session, IdleStatus status )
+    {
+        log.info(
+                "*** IDLE #" +
+                session.getIdleCount( IdleStatus.BOTH_IDLE ) +
+                " ***" );
     }
 
     public void exceptionCaught( IoSession session, Throwable cause )

Modified: directory/network/trunk/src/java/org/apache/mina/common/BaseIoSession.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/BaseIoSession.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/common/BaseIoSession.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/common/BaseIoSession.java Tue Sep  6 03:40:49 2005
@@ -31,6 +31,7 @@
 public abstract class BaseIoSession implements IoSession
 {
     private final Map attributes = new HashMap();
+    private final long creationTime;
 
     private long readBytes;
     private long writtenBytes;
@@ -39,14 +40,20 @@
     private long lastReadTime;
     private long lastWriteTime;
 
-    private boolean idleForBoth;
-    private boolean idleForRead;
-    private boolean idleForWrite;
+    private int idleCountForBoth;
+    private int idleCountForRead;
+    private int idleCountForWrite;
+    
+    private long lastIdleTimeForBoth;
+    private long lastIdleTimeForRead;
+    private long lastIdleTimeForWrite;
 
 
     protected BaseIoSession()
     {
-        lastReadTime = lastWriteTime = System.currentTimeMillis();
+        creationTime = lastReadTime = lastWriteTime =
+            lastIdleTimeForBoth = lastIdleTimeForRead = lastIdleTimeForWrite =
+                System.currentTimeMillis();
     }
     
     public Object getAttachment()
@@ -121,6 +128,11 @@
     {
         writtenWriteRequests ++;
     }
+    
+    public long getCreationTime()
+    {
+        return creationTime;
+    }
 
     public long getLastIoTime()
     {
@@ -140,25 +152,75 @@
     public boolean isIdle( IdleStatus status )
     {
         if( status == IdleStatus.BOTH_IDLE )
-            return idleForBoth;
+            return idleCountForBoth > 0;
+
+        if( status == IdleStatus.READER_IDLE )
+            return idleCountForRead > 0;
+
+        if( status == IdleStatus.WRITER_IDLE )
+            return idleCountForWrite > 0;
+
+        throw new IllegalArgumentException( "Unknown idle status: " + status );
+    }
+
+    public int getIdleCount( IdleStatus status )
+    {
+        if( status == IdleStatus.BOTH_IDLE )
+            return idleCountForBoth;
 
         if( status == IdleStatus.READER_IDLE )
-            return idleForRead;
+            return idleCountForRead;
 
         if( status == IdleStatus.WRITER_IDLE )
-            return idleForWrite;
+            return idleCountForWrite;
 
         throw new IllegalArgumentException( "Unknown idle status: " + status );
     }
+    
+    public long getLastIdleTime( IdleStatus status )
+    {
+        if( status == IdleStatus.BOTH_IDLE )
+            return lastIdleTimeForBoth;
+
+        if( status == IdleStatus.READER_IDLE )
+            return lastIdleTimeForRead;
+
+        if( status == IdleStatus.WRITER_IDLE )
+            return lastIdleTimeForWrite;
+
+        throw new IllegalArgumentException( "Unknown idle status: " + status );
+    }
+
+    public void increaseIdleCount( IdleStatus status )
+    {
+        if( status == IdleStatus.BOTH_IDLE )
+        {
+            idleCountForBoth ++;
+            lastIdleTimeForBoth = System.currentTimeMillis();
+        }
+        else if( status == IdleStatus.READER_IDLE )
+        {
+            idleCountForRead ++;
+            lastIdleTimeForRead = System.currentTimeMillis();
+        }
+        else if( status == IdleStatus.WRITER_IDLE )
+        {
+            idleCountForWrite ++;
+            lastIdleTimeForWrite = System.currentTimeMillis();
+        }
+        else
+            throw new IllegalArgumentException( "Unknown idle status: "
+                                                + status );
+    }
 
-    public void setIdle( IdleStatus status, boolean value )
+    public void resetIdleCount( IdleStatus status )
     {
         if( status == IdleStatus.BOTH_IDLE )
-            idleForBoth = value;
+            idleCountForBoth = 0;
         else if( status == IdleStatus.READER_IDLE )
-            idleForRead = value;
+            idleCountForRead = 0;
         else if( status == IdleStatus.WRITER_IDLE )
-            idleForWrite = value;
+            idleCountForWrite = 0;
         else
             throw new IllegalArgumentException( "Unknown idle status: "
                                                 + status );

Modified: directory/network/trunk/src/java/org/apache/mina/common/IoSession.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/IoSession.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/common/IoSession.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/common/IoSession.java Tue Sep  6 03:40:49 2005
@@ -152,6 +152,11 @@
     int getScheduledWriteRequests();
 
     /**
+     * Returns the time in millis when this session is created.
+     */
+    long getCreationTime();
+    
+    /**
      * Returns the time in millis when I/O occurred lastly.
      */
     long getLastIoTime();
@@ -171,4 +176,22 @@
      * {@link IdleStatus}.
      */
     boolean isIdle( IdleStatus status );
+
+    /**
+     * Returns the number of the fired continuous <tt>sessionIdle</tt> events
+     * for the specified {@link IdleStatus}.
+     * <p>
+     * If <tt>sessionIdle</tt> event is fired first after some time after I/O,
+     * <tt>idleCount</tt> becomes <tt>1</tt>.  <tt>idleCount</tt> resets to
+     * <tt>0</tt> if any I/O occurs again, otherwise it increases to
+     * <tt>2</tt> and so on if <tt>sessionIdle</tt> event is fired again without
+     * any I/O between two (or more) <tt>sessionIdle</tt> events.
+     */
+    int getIdleCount( IdleStatus status );
+    
+    /**
+     * Returns the time in millis when the last <tt>sessionIdle</tt> event
+     * is fired for the specified {@link IdleStatus}.
+     */
+    long getLastIdleTime( IdleStatus status );
 }

Modified: directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/SocketIoProcessor.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/SocketIoProcessor.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/SocketIoProcessor.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/SocketIoProcessor.java Tue Sep  6 03:40:49 2005
@@ -274,8 +274,8 @@
             }
 
             session.increaseReadBytes( readBytes );
-            session.setIdle( IdleStatus.BOTH_IDLE, false );
-            session.setIdle( IdleStatus.READER_IDLE, false );
+            session.resetIdleCount( IdleStatus.BOTH_IDLE );
+            session.resetIdleCount( IdleStatus.READER_IDLE );
 
             if( readBytes > 0 )
             {
@@ -345,15 +345,21 @@
     {
         IoSessionConfig config = session.getConfig();
 
-        notifyIdleSession0( session, currentTime, config
-                .getIdleTimeInMillis( IdleStatus.BOTH_IDLE ),
-                            IdleStatus.BOTH_IDLE, session.getLastIoTime() );
-        notifyIdleSession0( session, currentTime, config
-                .getIdleTimeInMillis( IdleStatus.READER_IDLE ),
-                            IdleStatus.READER_IDLE, session.getLastReadTime() );
-        notifyIdleSession0( session, currentTime, config
-                .getIdleTimeInMillis( IdleStatus.WRITER_IDLE ),
-                            IdleStatus.WRITER_IDLE, session.getLastWriteTime() );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.BOTH_IDLE ),
+                IdleStatus.BOTH_IDLE,
+                Math.max( session.getLastIoTime(), session.getLastIdleTime( IdleStatus.BOTH_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.READER_IDLE ),
+                IdleStatus.READER_IDLE,
+                Math.max( session.getLastReadTime(), session.getLastIdleTime( IdleStatus.READER_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.WRITER_IDLE ),
+                IdleStatus.WRITER_IDLE,
+                Math.max( session.getLastWriteTime(), session.getLastIdleTime( IdleStatus.WRITER_IDLE ) ) );
 
         notifyWriteTimeoutSession( session, currentTime, config
                 .getWriteTimeoutInMillis(), session.getLastWriteTime() );
@@ -363,10 +369,10 @@
                                     long idleTime, IdleStatus status,
                                     long lastIoTime )
     {
-        if( idleTime > 0 && !session.isIdle( status ) && lastIoTime != 0
+        if( idleTime > 0 && lastIoTime != 0
             && ( currentTime - lastIoTime ) >= idleTime )
         {
-            session.setIdle( status, true );
+            session.increaseIdleCount( status );
             session.getManagerFilterChain().sessionIdle( session, status );
         }
     }
@@ -500,8 +506,8 @@
                 if( writtenBytes > 0 )
                 {
                     session.increaseWrittenBytes( writtenBytes );
-                    session.setIdle( IdleStatus.BOTH_IDLE, false );
-                    session.setIdle( IdleStatus.WRITER_IDLE, false );
+                    session.resetIdleCount( IdleStatus.BOTH_IDLE );
+                    session.resetIdleCount( IdleStatus.WRITER_IDLE );
                 }
 
                 SelectionKey key = session.getSelectionKey();

Modified: directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeFilter.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeFilter.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeFilter.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeFilter.java Tue Sep  6 03:40:49 2005
@@ -20,8 +20,8 @@
     {
         VmPipeSession vps = ( VmPipeSession ) session;
 
-        vps.setIdle( IdleStatus.BOTH_IDLE, false );
-        vps.setIdle( IdleStatus.READER_IDLE, false );
+        vps.resetIdleCount( IdleStatus.BOTH_IDLE );
+        vps.resetIdleCount( IdleStatus.READER_IDLE );
         vps.increaseReadBytes( 1 );
 
         // fire messageSent event first
@@ -35,8 +35,8 @@
                              IoSession session, Object message )
     {
         VmPipeSession vps = ( VmPipeSession ) session;
-        vps.setIdle( IdleStatus.BOTH_IDLE, false );
-        vps.setIdle( IdleStatus.WRITER_IDLE, false );
+        vps.resetIdleCount( IdleStatus.BOTH_IDLE );
+        vps.resetIdleCount( IdleStatus.WRITER_IDLE );
         vps.increaseWrittenBytes( 1 );
         vps.increaseWrittenWriteRequests();
 

Modified: directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeIdleStatusChecker.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeIdleStatusChecker.java?rev=278969&r1=278968&r2=278969&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeIdleStatusChecker.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/transport/vmpipe/VmPipeIdleStatusChecker.java Tue Sep  6 03:40:49 2005
@@ -71,51 +71,45 @@
                         }
                         else
                         {
-                            long idleTime;
-                            IoSessionConfig config = session.getConfig();
-
-                            if( !session.isIdle( IdleStatus.BOTH_IDLE ) )
-                            {
-                                idleTime = config
-                                        .getIdleTimeInMillis( IdleStatus.BOTH_IDLE );
-                                session.setIdle( IdleStatus.BOTH_IDLE,
-                                                 idleTime > 0L
-                                                 && ( currentTime - session.getLastIoTime() ) > idleTime );
-                                if( session.isIdle( IdleStatus.BOTH_IDLE ) )
-                                    session.getManagerFilterChain()
-                                            .sessionIdle( session,
-                                                          IdleStatus.BOTH_IDLE );
-                            }
-
-                            if( !session.isIdle( IdleStatus.READER_IDLE ) )
-                            {
-                                idleTime = config
-                                        .getIdleTimeInMillis( IdleStatus.READER_IDLE );
-                                session.setIdle( IdleStatus.READER_IDLE,
-                                                 idleTime > 0L
-                                                 && ( currentTime - session.getLastReadTime() ) > idleTime );
-                                if( session.isIdle( IdleStatus.READER_IDLE ) )
-                                    session.getManagerFilterChain()
-                                            .sessionIdle( session,
-                                                          IdleStatus.READER_IDLE );
-                            }
-
-                            if( !session.isIdle( IdleStatus.WRITER_IDLE ) )
-                            {
-                                idleTime = config
-                                        .getIdleTimeInMillis( IdleStatus.WRITER_IDLE );
-                                session.setIdle( IdleStatus.WRITER_IDLE,
-                                                 idleTime > 0L
-                                                 && ( currentTime - session.getLastWriteTime() ) > idleTime );
-                                if( session.isIdle( IdleStatus.WRITER_IDLE ) )
-                                    session.getManagerFilterChain()
-                                            .sessionIdle( session,
-                                                          IdleStatus.WRITER_IDLE );
-                            }
+                            notifyIdleSession( session, currentTime );
                         }
                     }
                 }
             }
         }
     }
+    
+    private void notifyIdleSession( VmPipeSession session, long currentTime )
+    {
+        IoSessionConfig config = session.getConfig();
+
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.BOTH_IDLE ),
+                IdleStatus.BOTH_IDLE,
+                Math.max( session.getLastIoTime(), session.getLastIdleTime( IdleStatus.BOTH_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.READER_IDLE ),
+                IdleStatus.READER_IDLE,
+                Math.max( session.getLastReadTime(), session.getLastIdleTime( IdleStatus.READER_IDLE ) ) );
+        notifyIdleSession0(
+                session, currentTime,
+                config.getIdleTimeInMillis( IdleStatus.WRITER_IDLE ),
+                IdleStatus.WRITER_IDLE,
+                Math.max( session.getLastWriteTime(), session.getLastIdleTime( IdleStatus.WRITER_IDLE ) ) );
+    }
+
+    private void notifyIdleSession0( VmPipeSession session, long currentTime,
+                                    long idleTime, IdleStatus status,
+                                    long lastIoTime )
+    {
+        if( idleTime > 0 && lastIoTime != 0
+            && ( currentTime - lastIoTime ) >= idleTime )
+        {
+            session.increaseIdleCount( status );
+            session.getManagerFilterChain().sessionIdle( session, status );
+        }
+    }
+
 }