You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by el...@apache.org on 2008/10/19 21:40:21 UTC

svn commit: r706057 - in /mina/trunk: core/src/main/java/org/apache/mina/core/polling/ core/src/main/java/org/apache/mina/filter/logging/ core/src/main/java/org/apache/mina/filter/statistic/ core/src/main/java/org/apache/mina/filter/util/ core/src/main...

Author: elecharny
Date: Sun Oct 19 12:40:20 2008
New Revision: 706057

URL: http://svn.apache.org/viewvc?rev=706057&view=rev
Log:
o Added some javadoc
o Modified the select() method to return an int (sticking to the base semantic, and it can help to iterator through the SelectionKeys)
o Added some explicit constants

Modified:
    mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingConnectionlessIoAcceptor.java
    mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoAcceptor.java
    mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoConnector.java
    mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
    mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LogLevel.java
    mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LoggingFilter.java
    mina/trunk/core/src/main/java/org/apache/mina/filter/statistic/ProfilerTimerFilter.java
    mina/trunk/core/src/main/java/org/apache/mina/filter/util/ReferenceCountingFilter.java
    mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java
    mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramConnector.java
    mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
    mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketAcceptor.java
    mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketConnector.java
    mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java
    mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketAcceptor.java
    mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketConnector.java

Modified: mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingConnectionlessIoAcceptor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingConnectionlessIoAcceptor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingConnectionlessIoAcceptor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingConnectionlessIoAcceptor.java Sun Oct 19 12:40:20 2008
@@ -114,7 +114,7 @@
 
     protected abstract void init() throws Exception;
     protected abstract void destroy() throws Exception;
-    protected abstract boolean select(int timeout) throws Exception;
+    protected abstract int select(int timeout) throws Exception;
     protected abstract void wakeup();
     protected abstract Iterator<H> selectedHandles();
     protected abstract H open(SocketAddress localAddress) throws Exception;
@@ -333,11 +333,11 @@
 
             while (selectable) {
                 try {
-                    boolean selected = select(1000);
+                    int selected = select(1000);
 
                     nHandles += registerHandles();
 
-                    if (selected) {
+                    if (selected > 0) {
                         processReadySessions(selectedHandles());
                     }
 

Modified: mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoAcceptor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoAcceptor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoAcceptor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoAcceptor.java Sun Oct 19 12:40:20 2008
@@ -234,10 +234,10 @@
     /**
      * Check for acceptable connections, interrupt when at least a server is ready for accepting.
      * All the ready server socket descriptors need to be returned by {@link #selectedHandles()}
-     * @return true if one server socket have got incoming client
+     * @return The number of sockets having got incoming client
      * @throws Exception any exception thrown by the underlying systems calls
      */
-    protected abstract boolean select() throws Exception;
+    protected abstract int select() throws Exception;
 
     /**
      * Interrupt the {@link #select()} method. Used when the poll set need to be modified.
@@ -389,14 +389,14 @@
             while (selectable) {
                 try {
                     // Detect if we have some keys ready to be processed
-                    boolean selected = select();
+                    int selected = select();
 
                     // this actually sets the selector to OP_ACCEPT,
                     // and binds to the port in which this class will
                     // listen on
                     nHandles += registerHandles();
 
-                    if (selected) {
+                    if (selected > 0) {
                         processHandles(selectedHandles());
                     }
 

Modified: mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoConnector.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoConnector.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoConnector.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoConnector.java Sun Oct 19 12:40:20 2008
@@ -263,10 +263,10 @@
      * Check for connected sockets, interrupt when at least a connection is processed (connected or
      * failed to connect). All the client socket descriptors processed need to be returned by 
      * {@link #selectedHandles()}
-     * @return true if one server socket have got incoming client
+     * @return The number of socket having received some data
      * @throws Exception any exception thrown by the underlying systems calls
      */
-    protected abstract boolean select(int timeout) throws Exception;
+    protected abstract int select(int timeout) throws Exception;
     
     /**
      * {@link Iterator} for the set of client sockets found connected or 
@@ -462,11 +462,11 @@
                     // the timeout for select shall be smaller of the connect
                     // timeout or 1 second...
                     int timeout = (int)Math.min(getConnectTimeoutMillis(), 1000L);
-                    boolean selected = select(timeout);
+                    int selected = select(timeout);
 
                     nHandles += registerNew();
 
-                    if (selected) {
+                    if (selected > 0) {
                         nHandles -= processSessions(selectedHandles());
                     }
 

Modified: mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/core/polling/AbstractPollingIoProcessor.java Sun Oct 19 12:40:20 2008
@@ -181,10 +181,10 @@
     /**
      * poll those sessions for the given timeout
      * @param timeout milliseconds before the call timeout if no event appear
-     * @return true if at least a session is ready for read or for write
+     * @return The number of session ready for read or for write
      * @throws Exception if some low level IO error occurs
      */
-    protected abstract boolean select(int timeout) throws Exception;
+    protected abstract int select(int timeout) throws Exception;
     
     /**
      * Say if the list of {@link IoSession} polled by this {@link IoProcessor} 
@@ -852,12 +852,12 @@
 
             for (;;) {
                 try {
-                    boolean selected = select(1000);
+                    int selected = select(1000);
 
                     nSessions += add();
                     updateTrafficMask();
 
-                    if (selected) {
+                    if (selected > 0) {
                         process();
                     }
 

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LogLevel.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LogLevel.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LogLevel.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LogLevel.java Sun Oct 19 12:40:20 2008
@@ -19,141 +19,63 @@
  */
 package org.apache.mina.filter.logging;
 
-import org.slf4j.Logger;
-
 /**
  * Defines a logging level.
  * 
  * @author The Apache MINA Project (dev@mina.apache.org)
  * @version $Rev$, $Date$
  * 
- * @see LoggingFilter
+ * @see NoopFilter
  */
 public enum LogLevel {
 
     /**
-     * {@link LogLevel} which will not log any information
-     */
-    NONE(new LogLevelLogger() {
-        public void log(Logger logger, String message, Object arg) {
-            // Do nothing.
-        }
-
-        public void log(Logger logger, String message, Object[] args) {
-            // Do nothing.
-        }
-
-        public void log(Logger logger, String message, Throwable cause) {
-            // Do nothing.
-        }
-    }),
-
-    /**
      * {@link LogLevel} which logs messages on the TRACE level.
      */
-    TRACE(new LogLevelLogger() {
-        public void log(Logger logger, String message, Object arg) {
-            logger.trace(message, arg);
-        }
-
-        public void log(Logger logger, String message, Object[] args) {
-            logger.trace(message, args);
-        }
-
-        public void log(Logger logger, String message, Throwable cause) {
-            logger.trace(message, cause);
-        }
-    }),
-
+	TRACE(5),
+	
     /**
      * {@link LogLevel} which logs messages on the DEBUG level.
      */
-    DEBUG(new LogLevelLogger() {
-        public void log(Logger logger, String message, Object arg) {
-            logger.debug(message, arg);
-        }
-
-        public void log(Logger logger, String message, Object[] args) {
-            logger.debug(message, args);
-        }
-
-        public void log(Logger logger, String message, Throwable cause) {
-            logger.debug(message, cause);
-        }
-    }),
-
+	DEBUG(4),
+	
     /**
      * {@link LogLevel} which logs messages on the INFO level.
      */
-    INFO(new LogLevelLogger() {
-        public void log(Logger logger, String message, Object arg) {
-            logger.info(message, arg);
-        }
-
-        public void log(Logger logger, String message, Object[] args) {
-            logger.info(message, args);
-        }
-
-        public void log(Logger logger, String message, Throwable cause) {
-            logger.info(message, cause);
-        }
-    }),
-
+	INFO(3),
+	
     /**
      * {@link LogLevel} which logs messages on the WARN level.
      */
-    WARN(new LogLevelLogger() {
-        public void log(Logger logger, String message, Object arg) {
-            logger.warn(message, arg);
-        }
-
-        public void log(Logger logger, String message, Object[] args) {
-            logger.warn(message, args);
-        }
-
-        public void log(Logger logger, String message, Throwable cause) {
-            logger.warn(message, cause);
-        }
-    }),
-
+	WARN(2),
+	
     /**
      * {@link LogLevel} which logs messages on the ERROR level.
      */
-    ERROR(new LogLevelLogger() {
-        public void log(Logger logger, String message, Object arg) {
-            logger.error(message, arg);
-        }
-
-        public void log(Logger logger, String message, Object[] args) {
-            logger.error(message, args);
-        }
-
-        public void log(Logger logger, String message, Throwable cause) {
-            logger.error(message, cause);
-        }
-    });
-
-    private final LogLevelLogger logger;
-
-    private LogLevel(LogLevelLogger logger) {
-        this.logger = logger;
-    }
-
-    void log(Logger logger, String format, Object arg) {
-        this.logger.log(logger, format, arg);
-    }
-
-    void log(Logger logger, String format, Object[] args) {
-        this.logger.log(logger, format, args);
-    }
-
-    void log(Logger logger, String message, Throwable cause) {
-        this.logger.log(logger, message, cause);
-    }
+	ERROR(1),
+	
+    /**
+     * {@link LogLevel} which will not log any information
+     */
+	NONE(0);
 
-    private interface LogLevelLogger {
-        void log(Logger logger, String message, Object arg);
-        void log(Logger logger, String message, Object[] args);
-        void log(Logger logger, String message, Throwable cause);
-    }
+	/** The internal numeric value associated with the log level */
+	private int level;
+	
+	/**
+	 * Create a new instance of a LogLevel.
+	 * 
+	 * @param level The log level
+	 */
+	private LogLevel(int level) {
+		this.level = level;
+	}
+	
+	
+	/**
+	 * @return The numeric value associated with the log level 
+	 */
+	public int getLevel() {
+		return level;
+	}
 }
\ No newline at end of file

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LoggingFilter.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LoggingFilter.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LoggingFilter.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/logging/LoggingFilter.java Sun Oct 19 12:40:20 2008
@@ -19,15 +19,12 @@
  */
 package org.apache.mina.filter.logging;
 
-import java.util.Map;
-
 import org.apache.mina.core.filterchain.IoFilter;
 import org.apache.mina.core.filterchain.IoFilterAdapter;
 import org.apache.mina.core.session.IdleStatus;
 import org.apache.mina.core.session.IoEventType;
 import org.apache.mina.core.session.IoSession;
 import org.apache.mina.core.write.WriteRequest;
-import org.apache.mina.util.CopyOnWriteMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,278 +43,301 @@
  * @org.apache.xbean.XBean
  */
 public class LoggingFilter extends IoFilterAdapter {
-
-    private final Map<IoEventType, LogLevel> logSettings = new CopyOnWriteMap<IoEventType, LogLevel>();
+	/** The logger name */
     private final String name;
+    
+    /** The logger */
     private final Logger logger;
+    
+    /** The log level for the exceptionCaught event. Default to WARN. */
+    private LogLevel exceptionCaughtLevel = LogLevel.WARN;
+    
+    /** The log level for the messageSent event. Default to INFO. */
+    private LogLevel messageSentLevel = LogLevel.INFO;
+    
+    /** The log level for the messageReceived event. Default to INFO. */
+    private LogLevel messageReceivedLevel = LogLevel.INFO;
+    
+    /** The log level for the sessionCreated event. Default to INFO. */
+    private LogLevel sessionCreatedLevel = LogLevel.INFO;
+    
+    /** The log level for the sessionOpened event. Default to INFO. */
+    private LogLevel sessionOpenedLevel = LogLevel.INFO;
+    
+    /** The log level for the sessionIdle event. Default to INFO. */
+    private LogLevel sessionIdleLevel = LogLevel.INFO;
+    
+    /** The log level for the sessionClosed event. Default to INFO. */
+    private LogLevel sessionClosedLevel = LogLevel.INFO;
+    
     /**
      * Default Constructor.
      */
     public LoggingFilter() {
         this(LoggingFilter.class.getName());
     }
-
+    
+    /**
+     * Create a new NoopFilter using a class name
+     * 
+     * @param clazz the cass which name will be used to create the logger
+     */
     public LoggingFilter(Class<?> clazz) {
         this(clazz.getName());
     }
 
+    /**
+     * Create a new NoopFilter using a name
+     * 
+     * @param name the name used to create the logger. If null, will default to "NoopFilter"
+     */
     public LoggingFilter(String name) {
         if (name == null) {
-            throw new NullPointerException("name should not be null");
+            this.name = LoggingFilter.class.getName();
+        } else {
+        	this.name = name;
         }
-        this.name = name;
+        
         logger = LoggerFactory.getLogger(name);
-
-        // Exceptions will be logged to WARN as default.
-        setLogLevel(IoEventType.EXCEPTION_CAUGHT, LogLevel.WARN);
-        setLogLevel(IoEventType.MESSAGE_RECEIVED, LogLevel.INFO);
-        setLogLevel(IoEventType.MESSAGE_SENT, LogLevel.INFO);
-        setLogLevel(IoEventType.SESSION_CLOSED, LogLevel.INFO);
-        setLogLevel(IoEventType.SESSION_CREATED, LogLevel.INFO);
-        setLogLevel(IoEventType.SESSION_IDLE, LogLevel.INFO);
-        setLogLevel(IoEventType.SESSION_OPENED, LogLevel.INFO);
     }
 
+    /**
+     * @return The logger's name
+     */
     public String getName() {
         return name;
     }
+    
+    /**
+     * Log if the logger and the current event log level are compatible. We log
+     * a message and an exception.
+     * 
+     * @param eventLevel the event log level as requested by the user
+     * @param message the message to log
+     * @param cause the exception cause to log
+     */
+    private void log(LogLevel eventLevel, String message, Throwable cause) {
+    	if (eventLevel == LogLevel.TRACE) {
+    		logger.trace(message, cause);
+    	} else if (eventLevel.getLevel() > LogLevel.INFO.getLevel()) {
+    		logger.info(message, cause);
+    	} else if (eventLevel.getLevel() > LogLevel.WARN.getLevel()) {
+    		logger.warn(message, cause);
+    	} else if (eventLevel.getLevel() > LogLevel.ERROR.getLevel()) {
+    		logger.error(message, cause);
+    	}
+    }
+
+    /**
+     * Log if the logger and the current event log level are compatible. We log
+     * a formated message and its parameters. 
+     * 
+     * @param eventLevel the event log level as requested by the user
+     * @param message the formated message to log
+     * @param param the parameter injected into the message
+     */
+    private void log(LogLevel eventLevel, String message, Object param) {
+    	if (eventLevel == LogLevel.TRACE) {
+    		logger.trace(message, param);
+    	} else if (eventLevel.getLevel() > LogLevel.INFO.getLevel()) {
+    		logger.info(message, param);
+    	} else if (eventLevel.getLevel() > LogLevel.WARN.getLevel()) {
+    		logger.warn(message, param);
+    	} else if (eventLevel.getLevel() > LogLevel.ERROR.getLevel()) {
+    		logger.error(message, param);
+    	} 
+    }
+
+    /**
+     * Log if the logger and the current event log level are compatible. We log
+     * a simple message. 
+     * 
+     * @param eventLevel the event log level as requested by the user
+     * @param message the message to log
+     */
+    private void log(LogLevel eventLevel, String message) {
+    	if (eventLevel == LogLevel.TRACE) {
+    		logger.trace(message);
+    	} else if (eventLevel.getLevel() > LogLevel.INFO.getLevel()) {
+    		logger.info(message);
+    	} else if (eventLevel.getLevel() > LogLevel.WARN.getLevel()) {
+    		logger.warn(message);
+    	} else if (eventLevel.getLevel() > LogLevel.ERROR.getLevel()) {
+    		logger.error(message);
+    	}
+    }
 
     @Override
     public void exceptionCaught(NextFilter nextFilter, IoSession session,
             Throwable cause) throws Exception {
-        getLogLevel(IoEventType.EXCEPTION_CAUGHT).log(logger, "EXCEPTION: ", cause);
+    	log(exceptionCaughtLevel, "EXCEPTION :", cause);
         nextFilter.exceptionCaught(session, cause);
     }
 
     @Override
     public void messageReceived(NextFilter nextFilter, IoSession session,
             Object message) throws Exception {
-        log(IoEventType.MESSAGE_RECEIVED, "RECEIVED: {}", message);
-        nextFilter.messageReceived(session, message);
+    	log(messageReceivedLevel, "RECEIVED: {}", message );
+    	nextFilter.messageReceived(session, message);
     }
 
     @Override
     public void messageSent(NextFilter nextFilter, IoSession session,
             WriteRequest writeRequest) throws Exception {
-        log(IoEventType.MESSAGE_SENT, "SENT: {}", writeRequest.getMessage());
+    	log(messageSentLevel, "SENT: {}", writeRequest.getMessage() );
         nextFilter.messageSent(session, writeRequest);
     }
 
     @Override
-    public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
-        log(IoEventType.SESSION_CLOSED, "CLOSED", null);
-        nextFilter.sessionClosed(session);
+    public void sessionCreated(NextFilter nextFilter, IoSession session)
+    		throws Exception {
+    	log(sessionCreatedLevel, "CREATED");
+        nextFilter.sessionCreated(session);
     }
 
     @Override
-    public void sessionCreated(NextFilter nextFilter, IoSession session)
+    public void sessionOpened(NextFilter nextFilter, IoSession session)
     throws Exception {
-        log(IoEventType.SESSION_CREATED, "CREATED", null);
-        nextFilter.sessionCreated(session);
+    	log(sessionOpenedLevel, "OPENED");
+        nextFilter.sessionOpened(session);
     }
 
     @Override
     public void sessionIdle(NextFilter nextFilter, IoSession session,
             IdleStatus status) throws Exception {
-        log(IoEventType.SESSION_IDLE, "IDLE: {}", status);
+    	log(sessionIdleLevel, "IDLE");
         nextFilter.sessionIdle(session, status);
     }
 
     @Override
-    public void sessionOpened(NextFilter nextFilter, IoSession session)
-    throws Exception {
-        log(IoEventType.SESSION_OPENED, "OPENED", null);
-        nextFilter.sessionOpened(session);
+    public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
+    	log(sessionClosedLevel, "CLOSED");
+        nextFilter.sessionClosed(session);
     }
-
+    
     /**
-     * Logs the specified event.
+     * Set the LogLevel for the ExceptionCaught event.
      * 
-     * @param eventType the type of the event
-     * @param format    the message (or SLF4J format string)
-     * @param arg       the argument of the SLF4J format string
-     */
-    protected void log(IoEventType eventType, String format, Object arg) {
-        getLogLevel(eventType).log(logger, format, arg);
-    }
-
-    /**
-     * Sets the {@link LogLevel} to be used when exceptions are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when exceptions are logged.
-     */
-    public void setExceptionCaughtLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.EXCEPTION_CAUGHT, logLevel);
-    }
-
-    /**
-     * Sets the {@link LogLevel} to be used when message received events are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when message received events are logged.
-     */
-    public void setMessageReceivedLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.MESSAGE_RECEIVED, logLevel);
-    }
-
-    /**
-     * Sets the {@link LogLevel} to be used when message sent events are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when message sent events are logged.
+     * @param level The LogLevel to set
      */
-    public void setMessageSentLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.MESSAGE_SENT, logLevel);
+    public void setExceptionCaughtLoglevel(LogLevel level) {
+    	exceptionCaughtLevel = level;
     }
-
+    
     /**
-     * Sets the {@link LogLevel} to be used when session closed events are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when session closed events are logged.
+     * Get the LogLevel for the ExceptionCaught event.
+     * 
+     * @return The LogLevel for the ExceptionCaught eventType
      */
-    public void setSessionClosedLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.SESSION_CLOSED, logLevel);
+    public LogLevel getExceptionCaughtLoglevel() {
+    	return exceptionCaughtLevel;
     }
-
+    
     /**
-     * Sets the {@link LogLevel} to be used when session created events are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when session created events are logged.
+     * Set the LogLevel for the MessageReceived event.
+     * 
+     * @param level The LogLevel to set
      */
-    public void setSessionCreatedLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.SESSION_CREATED, logLevel);
+    public void setMessageReceivedLoglevel(LogLevel level) {
+    	messageReceivedLevel = level;
     }
-
+    
     /**
-     * Sets the {@link LogLevel} to be used when session idle events are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when session idle events are logged.
+     * Get the LogLevel for the MessageReceived event.
+     * 
+     * @return The LogLevel for the MessageReceived eventType
      */
-    public void setSessionIdleLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.SESSION_IDLE, logLevel);
+    public LogLevel getMessageReceivedLoglevel() {
+    	return messageReceivedLevel;
     }
-
+    
     /**
-     * Sets the {@link LogLevel} to be used when session opened events are logged.
-     *
-     * @param logLevel
-     * 	The {@link LogLevel} to be used when session opened events are logged.
+     * Set the LogLevel for the MessageSent event.
+     * 
+     * @param level The LogLevel to set
      */
-    public void setSessionOpenedLogLevel(LogLevel logLevel) {
-        setLogLevel(IoEventType.SESSION_OPENED, logLevel);
+    public void setMessageSentLoglevel(LogLevel level) {
+    	messageSentLevel = level;
     }
-
+    
     /**
-     * This method sets the log level for the supplied {@link LogLevel}
-     * event.
-     *
-     * @param eventType the type of the event that is to be updated with
-     *                  the new {@link LogLevel}
-     * @param logLevel  the new {@link LogLevel} to be used to log the
-     *                  specified event
+     * Get the LogLevel for the MessageSent event.
+     * 
+     * @return The LogLevel for the MessageSent eventType
      */
-    public void setLogLevel(IoEventType eventType, LogLevel logLevel) {
-        if (eventType == null) {
-            throw new NullPointerException("eventType");
-        }
-        if (logLevel == null) {
-            throw new NullPointerException("logLevel");
-        }
-
-        logSettings.put(eventType, logLevel);
+    public LogLevel getMessageSentLoglevel() {
+    	return messageSentLevel;
     }
-
+    
     /**
-     * Returns the log level for the supplied event type.
-     *
-     * @param eventType the type of the event
+     * Set the LogLevel for the SessionCreated event.
+     * 
+     * @param level The LogLevel to set
      */
-    public LogLevel getLogLevel(IoEventType eventType) {
-        if (eventType == null) {
-            throw new NullPointerException("eventType");
-        }
-
-        return logSettings.get(eventType);
+    public void setSessionCreatedLoglevel(LogLevel level) {
+    	sessionCreatedLevel = level;
     }
-
+    
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * exception caught events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging exception caught events
+     * Get the LogLevel for the SessionCreated event.
+     * 
+     * @return The LogLevel for the SessionCreated eventType
      */
-    public LogLevel getExceptionCaughtLogLevel() {
-        return getLogLevel(IoEventType.EXCEPTION_CAUGHT);
+    public LogLevel getSessionCreatedLoglevel() {
+    	return sessionCreatedLevel;
     }
-
+    
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * message received events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging message received events
+     * Set the LogLevel for the SessionOpened event.
+     * 
+     * @param level The LogLevel to set
      */
-    public LogLevel getMessageReceivedLogLevel() {
-        return getLogLevel(IoEventType.MESSAGE_RECEIVED);
+    public void setSessionOpenedLoglevel(LogLevel level) {
+    	sessionOpenedLevel = level;
     }
-
+    
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * message sent events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging message sent events
+     * Get the LogLevel for the SessionOpened event.
+     * 
+     * @return The LogLevel for the SessionOpened eventType
      */
-    public LogLevel getMessageSentLogLevel() {
-        return getLogLevel(IoEventType.MESSAGE_SENT);
+    public LogLevel getSessionOpenedLoglevel() {
+    	return sessionOpenedLevel;
     }
-
+    
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * session closed events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging session closed events
+     * Set the LogLevel for the SessionIdle event.
+     * 
+     * @param level The LogLevel to set
      */
-    public LogLevel getSessionClosedLogLevel() {
-        return getLogLevel(IoEventType.SESSION_CLOSED);
+    public void setSessionIdleLoglevel(LogLevel level) {
+    	sessionIdleLevel = level;
     }
-
+    
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * session created events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging session created events
+     * Get the LogLevel for the SessionIdle event.
+     * 
+     * @return The LogLevel for the SessionIdle eventType
      */
-    public LogLevel getSessionCreatedLogLevel() {
-        return getLogLevel(IoEventType.SESSION_CREATED);
+    public LogLevel getSessionIdleLoglevel() {
+    	return sessionIdleLevel;
     }
-
+    
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * session idle events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging session idle events
+     * Set the LogLevel for the SessionClosed event.
+     * 
+     * @param level The LogLevel to set
      */
-    public LogLevel getSessionIdleLogLevel() {
-        return getLogLevel(IoEventType.SESSION_IDLE);
+    public void setSessionClosedLoglevel(LogLevel level) {
+    	sessionClosedLevel = level;
     }
 
     /**
-     * This method returns the {@link LogLevel} that is used to log
-     * session opened events.
-     *
-     * @return
-     * 	The {@link LogLevel} used when logging session opened events
+     * Get the LogLevel for the SessionClosed event.
+     * 
+     * @return The LogLevel for the SessionClosed eventType
      */
-    public LogLevel getSessionOpenedLogLevel() {
-        return getLogLevel(IoEventType.SESSION_OPENED);
+    public LogLevel getSessionClosedLoglevel() {
+    	return sessionClosedLevel;
     }
 }

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/statistic/ProfilerTimerFilter.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/statistic/ProfilerTimerFilter.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/statistic/ProfilerTimerFilter.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/statistic/ProfilerTimerFilter.java Sun Oct 19 12:40:20 2008
@@ -19,9 +19,7 @@
  */
 package org.apache.mina.filter.statistic;
 
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Map;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -31,10 +29,9 @@
 import org.apache.mina.core.session.IoEventType;
 import org.apache.mina.core.session.IoSession;
 import org.apache.mina.core.write.WriteRequest;
-import org.apache.mina.util.CopyOnWriteMap;
 
 /**
- * This class will measure, the time it takes for a
+ * This class will measure the time it takes for a
  * method in the {@link IoFilterAdapter} class to execute.  The basic
  * premise of the logic in this class is to get the current time
  * at the beginning of the method, call method on nextFilter, and
@@ -46,16 +43,60 @@
  *         TimeUnit.MILLISECOND, IoEventType.MESSAGE_RECEIVED);
  * chain.addFirst("Profiler", profiler);
  * </pre>
+ * 
+ * The profiled {@link IoEventType} are :
+ * <ul>
+ * <li>IoEventType.MESSAGE_RECEIVED</li>
+ * <li>IoEventType.MESSAGE_SENT</li>
+ * <li>IoEventType.SESSION_CREATED</li>
+ * <li>IoEventType.SESSION_OPENED</li>
+ * <li>IoEventType.SESSION_IDLE</li>
+ * <li>IoEventType.SESSION_CLOSED</li>
+ * </ul>
  *
  * @author The Apache MINA Project (dev@mina.apache.org)
  * @version $Rev$, $Date$
  * @org.apache.xbean.XBean
  */
 public class ProfilerTimerFilter extends IoFilterAdapter {
+    /** TRhe selected time unit */
+    private volatile TimeUnit timeUnit;
     
-    private volatile EnumSet<IoEventType> eventsToProfile;
-    private volatile ProfilerTimerUnit timeUnit;
-    private final Map<IoEventType, TimerWorker> timerManager;
+    /** A TimerWorker for the MessageReceived events */
+    private TimerWorker messageReceivedTimerWorker;
+    
+    /** A flag to tell the filter that the MessageReceived must be profiled */
+    private boolean profileMessageReceived = false;
+
+    /** A TimerWorker for the MessageSent events */
+    private TimerWorker messageSentTimerWorker;
+
+    /** A flag to tell the filter that the MessageSent must be profiled */
+    private boolean profileMessageSent = false;
+
+    /** A TimerWorker for the SessionCreated events */
+    private TimerWorker sessionCreatedTimerWorker;
+
+    /** A flag to tell the filter that the SessionCreated must be profiled */
+    private boolean profileSessionCreated = false;
+
+    /** A TimerWorker for the SessionOpened events */
+    private TimerWorker sessionOpenedTimerWorker;
+
+    /** A flag to tell the filter that the SessionOpened must be profiled */
+    private boolean profileSessionOpened = false;
+
+    /** A TimerWorker for the SessionIdle events */
+    private TimerWorker sessionIdleTimerWorker;
+
+    /** A flag to tell the filter that the SessionIdle must be profiled */
+    private boolean profileSessionIdle = false;
+
+    /** A TimerWorker for the SessionClosed events */
+    private TimerWorker sessionClosedTimerWorker;
+
+    /** A flag to tell the filter that the SessionClosed must be profiled */
+    private boolean profileSessionClosed = false;
 
     /**
      * Creates a new instance of ProfilerFilter.  This is the
@@ -65,19 +106,20 @@
      */
     public ProfilerTimerFilter() {
         this(
-                TimeUnit.MILLISECONDS, EnumSet.of(IoEventType.MESSAGE_RECEIVED,
-                                IoEventType.MESSAGE_SENT));
+                TimeUnit.MILLISECONDS, 
+                IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
     }
     
     /**
      * Creates a new instance of ProfilerFilter.  This is the
      * default constructor and will print out timings for
-     * messageReceived and messageSent and the time increment
-     * will be in milliseconds.
+     * messageReceived and messageSent.
+     * 
+     * @param timeUnit the time increment to set
      */
-    public ProfilerTimerFilter(TimeUnit unit) {
+    public ProfilerTimerFilter(TimeUnit timeUnit) {
         this(
-                unit, 
+        		timeUnit, 
                 IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
     }
     
@@ -90,201 +132,352 @@
      *         TimeUnit.MILLISECONDS,
      *         IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
      * </pre>
-     * @param unit
-     *  Used to determine the level of precision you need in your timing.
-     * @param firstEventType an event type to profile
-     * @param otherEventTypes event types to profile
+     * 
+     * Note : you can add as many {@link IoEventType} as you want. The method accepts
+     * a variable number of arguments.
+     * 
+     * @param timeUnit Used to determine the level of precision you need in your timing.
+     * @param eventTypes A list of {@link IoEventType} representation of the methods to profile
      */
-    public ProfilerTimerFilter(TimeUnit unit, IoEventType firstEventType, IoEventType... otherEventTypes) {
-        this(unit, EnumSet.of(firstEventType, otherEventTypes));
-    }
-
+    public ProfilerTimerFilter(TimeUnit timeUnit, IoEventType... eventTypes) {
+        this.timeUnit = timeUnit;
 
-    /**
-     * Creates a new instance of ProfilerFilter.  An example
-     * of this call would be:
-     *
-     * <pre>
-     * new ProfilerTimerFilter(
-     *         TimeUnit.MILLISECONDS,
-     *         EnumSet.of(IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT));
-     * </pre>
-     * @param unit
-     *  Used to determine the level of precision you need in your timing.
-     * @param eventTypes
-     *  A set of {@link IoEventType} representation of the methods to profile
-     */
-    public ProfilerTimerFilter(TimeUnit unit, EnumSet<IoEventType> eventTypes) {
-        setTimeUnit(unit);
-        setEventsToProfile(eventTypes);
-
-        timerManager = new CopyOnWriteMap<IoEventType, TimerWorker>();
-        for (IoEventType type : eventsToProfile) {
-            timerManager.put(type, new TimerWorker());
-        }
+        setProfilers(eventTypes);
     }
-
+    
     /**
-     * Sets the {@link TimeUnit} being used.
-     *
-     * @param unit the new {@link TimeUnit} to be used.
-     */
-    public void setTimeUnit(TimeUnit unit) {
-        if (unit == TimeUnit.MILLISECONDS) {
-            this.timeUnit = ProfilerTimerUnit.MILLISECONDS;
-        } else if (unit == TimeUnit.NANOSECONDS) {
-            this.timeUnit = ProfilerTimerUnit.NANOSECONDS;
-        } else if (unit == TimeUnit.SECONDS) {
-            this.timeUnit = ProfilerTimerUnit.SECONDS;
-        } else {
-            throw new IllegalArgumentException(
-                    "Invalid Time specified: " + unit + " (expected: " +
-                    TimeUnit.MILLISECONDS + ", " +
-                    TimeUnit.NANOSECONDS + " or " +
-                    TimeUnit.SECONDS + ')');
+     * Create the profilers for a list of {@link IoEventType}.
+     * 
+     * @param eventTypes the list of {@link IoEventType} to profile
+     */
+    private void setProfilers(IoEventType... eventTypes) {
+        for (IoEventType type : eventTypes) {
+        	switch (type) {
+	        	case MESSAGE_RECEIVED :
+	        		messageReceivedTimerWorker = new TimerWorker();
+	        		profileMessageReceived = true;
+	        		break;
+
+	        	case MESSAGE_SENT :
+	        		messageSentTimerWorker = new TimerWorker();
+	        		profileMessageSent = true;
+	        		break;
+
+	        	case SESSION_CREATED :
+	        		sessionCreatedTimerWorker = new TimerWorker();
+	        		profileSessionCreated = true;
+	        		break;
+	        		
+	        	case SESSION_OPENED :
+	        		sessionOpenedTimerWorker = new TimerWorker();
+	        		profileSessionOpened = true;
+	        		break;
+	        		
+	        	case SESSION_IDLE :
+	        		sessionIdleTimerWorker = new TimerWorker();
+	        		profileSessionIdle = true;
+	        		break;
+	        		
+	        	case SESSION_CLOSED :
+	        		sessionClosedTimerWorker = new TimerWorker();
+	        		profileSessionClosed = true;
+	        		break;
+        	}
         }
     }
 
     /**
-     * Add an {@link IoEventType} to profile
+     * Sets the {@link TimeUnit} being used.
      *
-     * @param type
-     *  The {@link IoEventType} to profile
+     * @param timeUnit the new {@link TimeUnit} to be used.
      */
-    public void addEventToProfile(IoEventType type) {
-        if (!timerManager.containsKey(type)) {
-            timerManager.put(type, new TimerWorker());
-        }
+    public void setTimeUnit(TimeUnit timeUnit) {
+    	this.timeUnit = timeUnit;
     }
 
     /**
-     * Remove an {@link IoEventType} to profile
+     * Set the {@link IoEventType} to be profiled
      *
-     * @param type
-     *  The {@link IoEventType} to profile
-     */
-    public void removeEventToProfile(IoEventType type) {
-        timerManager.remove(type);
+     * @param type The {@link IoEventType} to profile
+     */
+    public void profile(IoEventType type) {
+    	switch (type) {
+    		case MESSAGE_RECEIVED :
+	    		profileMessageReceived = true;
+	    		
+	    		if (messageReceivedTimerWorker == null) {
+	    			messageReceivedTimerWorker = new TimerWorker();
+	    		}
+    	    	
+    	    	return;
+    			
+    		case MESSAGE_SENT :
+	    		profileMessageSent = true;
+	    		
+	    		if (messageSentTimerWorker == null) {
+	    			messageSentTimerWorker = new TimerWorker();
+	    		}
+    	    	
+    	    	return;
+    	    	
+    		case SESSION_CREATED :
+				profileSessionCreated = true;
+	    		
+	    		if (sessionCreatedTimerWorker == null) {
+	    			sessionCreatedTimerWorker = new TimerWorker();
+	    		}
+    	    	
+    		case SESSION_OPENED :
+				profileSessionOpened = true;
+	    		
+	    		if (sessionOpenedTimerWorker == null) {
+	    			sessionOpenedTimerWorker = new TimerWorker();
+	    		}
+    	    	
+    		case SESSION_IDLE :
+				profileSessionIdle = true;
+	    		
+	    		if (sessionIdleTimerWorker == null) {
+	    			sessionIdleTimerWorker = new TimerWorker();
+	    		}
+    	    	
+    		case SESSION_CLOSED :
+				profileSessionClosed = true;
+	    		
+	    		if (sessionClosedTimerWorker == null) {
+	    			sessionClosedTimerWorker = new TimerWorker();
+	    		}
+    	}
+    }
+
+    /**
+     * Stop profiling an {@link IoEventType}
+     *
+     * @param type The {@link IoEventType} to stop profiling
+     */
+    public void stopProfile(IoEventType type) {
+    	switch (type) {
+			case MESSAGE_RECEIVED :
+	    		profileMessageReceived = false;
+		    	return;
+				
+			case MESSAGE_SENT :
+				profileMessageSent = false;
+		    	return;
+		    	
+			case SESSION_CREATED :
+				profileSessionCreated = false;
+				return;
+
+			case SESSION_OPENED :
+				profileSessionOpened = false;
+				return;
+
+			case SESSION_IDLE :
+				profileSessionIdle = false;
+				return;
+
+			case SESSION_CLOSED :
+				profileSessionClosed = false;
+				return;
+    	}
     }
 
     /**
-     * Return the bitmask that is being used to display
-     * timing information for this filter.
+     * Return the set of {@link IoEventType} which are profiled.
      *
-     * @return
-     *  An int representing the methods that will be logged
+     * @return a Set containing all the profiled {@link IoEventType} 
      */
     public Set<IoEventType> getEventsToProfile() {
-        return Collections.unmodifiableSet(eventsToProfile);
+    	Set<IoEventType> set = new HashSet<IoEventType>();
+    	
+    	if ( profileMessageReceived ) {
+    		set.add(IoEventType.MESSAGE_RECEIVED);
+    	}
+    	
+    	if ( profileMessageSent) {
+    		set.add(IoEventType.MESSAGE_SENT);
+    	}
+    	
+    	if ( profileSessionCreated ) {
+    		set.add(IoEventType.SESSION_CREATED);
+    	}
+    	
+    	if ( profileSessionOpened ) {
+    		set.add(IoEventType.SESSION_OPENED);
+    	}
+    	
+    	if ( profileSessionIdle ) {
+    		set.add(IoEventType.SESSION_IDLE);
+    	}
+    	
+    	if ( profileSessionClosed ) {
+    		set.add(IoEventType.SESSION_CLOSED);
+    	}
+    	
+        return set;
     }
 
     /**
-     * Set the bitmask in order to tell this filter which
-     * methods to print out timing information
-     */
-    public void setEventsToProfile(IoEventType firstEventType, IoEventType... otherEventTypes) {
-        this.setEventsToProfile(EnumSet.of(firstEventType, otherEventTypes));
+     * Set the profilers for a list of {@link IoEventType}
+     * 
+     * @param eventTypes the list of {@link IoEventType} to profile
+     */
+    public void setEventsToProfile(IoEventType... eventTypes) {
+        setProfilers(eventTypes);
     }
 
     /**
-     * Set the bitmask in order to tell this filter which
-     * methods to print out timing information
-     *
-     * @param eventTypes
-     *  An int representing the new methods that should be logged
+     * Profile a MessageReceived event. This method will gather the following
+     * informations :
+     * - the method duration
+     * - the shortest execution time
+     * - the slowest execution time
+     * - the average execution time
+     * - the global number of calls
+     * 
+     * @param nextFilter The filter to call next
+     * @param session The associated session
+     * @param message the received message
      */
-    public void setEventsToProfile(Set<IoEventType> eventTypes) {
-        if (eventTypes == null) {
-            throw new NullPointerException("eventTypes");
-        }
-        if (eventTypes.isEmpty()) {
-            throw new IllegalArgumentException("eventTypes is empty.");
-        }
-
-        EnumSet<IoEventType> newEventsToProfile = EnumSet.noneOf(IoEventType.class);
-        for (IoEventType e: eventTypes) {
-            newEventsToProfile.add(e);
-        }
-        
-        this.eventsToProfile = newEventsToProfile;
-    }
-
     @Override
     public void messageReceived(NextFilter nextFilter, IoSession session,
             Object message) throws Exception {
-        long start = timeUnit.timeNow();
-        nextFilter.messageReceived(session, message);
-        long end = timeUnit.timeNow();
-
-        if (getEventsToProfile().contains(IoEventType.MESSAGE_RECEIVED)) {
-            timerManager.get(IoEventType.MESSAGE_RECEIVED).addNewReading(
-                    end - start);
-        }
+    	if (profileMessageReceived) {
+	        long start = timeNow();
+	        nextFilter.messageReceived(session, message);
+	        long end = timeNow();
+	        messageReceivedTimerWorker.addNewDuration(end - start);
+    	} else {
+	        nextFilter.messageReceived(session, message);
+    	}
     }
 
+    /**
+     * Profile a MessageSent event. This method will gather the following
+     * informations :
+     * - the method duration
+     * - the shortest execution time
+     * - the slowest execution time
+     * - the average execution time
+     * - the global number of calls
+     * 
+     * @param nextFilter The filter to call next
+     * @param session The associated session
+     * @param writeRequest the sent message
+     */
     @Override
     public void messageSent(NextFilter nextFilter, IoSession session,
             WriteRequest writeRequest) throws Exception {
-        long start = timeUnit.timeNow();
-        nextFilter.messageSent(session, writeRequest);
-        long end = timeUnit.timeNow();
-
-        if (getEventsToProfile().contains(IoEventType.MESSAGE_SENT)) {
-            timerManager.get(IoEventType.MESSAGE_SENT).addNewReading(
-                    end - start);
-        }
+    	if (profileMessageSent) {
+	        long start = timeNow();
+	        nextFilter.messageSent(session, writeRequest);
+	        long end = timeNow();
+	        messageSentTimerWorker.addNewDuration(end - start);
+    	} else {
+	        nextFilter.messageSent(session, writeRequest);
+    	}
     }
 
+    /**
+     * Profile a SessionCreated event. This method will gather the following
+     * informations :
+     * - the method duration
+     * - the shortest execution time
+     * - the slowest execution time
+     * - the average execution time
+     * - the global number of calls
+     * 
+     * @param nextFilter The filter to call next
+     * @param session The associated session
+     */
     @Override
-    public void sessionClosed(NextFilter nextFilter, IoSession session)
+    public void sessionCreated(NextFilter nextFilter, IoSession session)
             throws Exception {
-        long start = timeUnit.timeNow();
-        nextFilter.sessionClosed(session);
-        long end = timeUnit.timeNow();
-
-        if (getEventsToProfile().contains(IoEventType.SESSION_CLOSED)) {
-            timerManager.get(IoEventType.SESSION_CLOSED).addNewReading(
-                    end - start);
-        }
+    	if (profileSessionCreated) {
+	        long start = timeNow();
+	        nextFilter.sessionCreated(session);
+	        long end = timeNow();
+	        sessionCreatedTimerWorker.addNewDuration(end - start);
+    	} else {
+            nextFilter.sessionCreated(session);
+    	}
     }
 
+    /**
+     * Profile a SessionOpened event. This method will gather the following
+     * informations :
+     * - the method duration
+     * - the shortest execution time
+     * - the slowest execution time
+     * - the average execution time
+     * - the global number of calls
+     * 
+     * @param nextFilter The filter to call next
+     * @param session The associated session
+     */
     @Override
-    public void sessionCreated(NextFilter nextFilter, IoSession session)
+    public void sessionOpened(NextFilter nextFilter, IoSession session)
             throws Exception {
-        long start = timeUnit.timeNow();
-        nextFilter.sessionCreated(session);
-        long end = timeUnit.timeNow();
-
-        if (getEventsToProfile().contains(IoEventType.SESSION_CREATED)) {
-            timerManager.get(IoEventType.SESSION_CREATED).addNewReading(
-                    end - start);
-        }
+    	if (profileSessionOpened) {
+	        long start = timeNow();
+	        nextFilter.sessionOpened(session);
+	        long end = timeNow();
+	        sessionOpenedTimerWorker.addNewDuration(end - start);
+    	} else {
+            nextFilter.sessionOpened(session);
+    	}
     }
 
+    /**
+     * Profile a SessionIdle event. This method will gather the following
+     * informations :
+     * - the method duration
+     * - the shortest execution time
+     * - the slowest execution time
+     * - the average execution time
+     * - the global number of calls
+     * 
+     * @param nextFilter The filter to call next
+     * @param session The associated session
+     * @param status The session's status
+     */
     @Override
     public void sessionIdle(NextFilter nextFilter, IoSession session,
             IdleStatus status) throws Exception {
-        long start = timeUnit.timeNow();
-        nextFilter.sessionIdle(session, status);
-        long end = timeUnit.timeNow();
-
-        if (getEventsToProfile().contains(IoEventType.SESSION_IDLE)) {
-            timerManager.get(IoEventType.SESSION_IDLE).addNewReading(
-                    end - start);
-        }
+    	if (profileSessionIdle) {
+	        long start = timeNow();
+	        nextFilter.sessionIdle(session, status);
+	        long end = timeNow();
+	        sessionIdleTimerWorker.addNewDuration(end - start);
+    	} else {
+            nextFilter.sessionIdle(session, status);
+    	}
     }
 
+    /**
+     * Profile a SessionClosed event. This method will gather the following
+     * informations :
+     * - the method duration
+     * - the shortest execution time
+     * - the slowest execution time
+     * - the average execution time
+     * - the global number of calls
+     * 
+     * @param nextFilter The filter to call next
+     * @param session The associated session
+     */
     @Override
-    public void sessionOpened(NextFilter nextFilter, IoSession session)
+    public void sessionClosed(NextFilter nextFilter, IoSession session)
             throws Exception {
-        long start = timeUnit.timeNow();
-        nextFilter.sessionOpened(session);
-        long end = timeUnit.timeNow();
-
-        if (getEventsToProfile().contains(IoEventType.SESSION_OPENED)) {
-            timerManager.get(IoEventType.SESSION_OPENED).addNewReading(
-                    end - start);
-        }
+    	if (profileSessionClosed) {
+	        long start = timeNow();
+	        nextFilter.sessionClosed(session);
+	        long end = timeNow();
+	        sessionClosedTimerWorker.addNewDuration(end - start);
+    	} else {
+            nextFilter.sessionClosed(session);
+    	}
     }
 
     /**
@@ -296,12 +489,52 @@
      *  The average time it took to execute the method represented by the {@link IoEventType}
      */
     public double getAverageTime(IoEventType type) {
-        if (!timerManager.containsKey(type)) {
-            throw new IllegalArgumentException(
-                    "You are not monitoring this event.  Please add this event first.");
-        }
+    	switch (type) {
+	    	case MESSAGE_RECEIVED :
+	    		if (profileMessageReceived) {
+	    			return messageReceivedTimerWorker.getAverage();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case MESSAGE_SENT :
+	    		if (profileMessageSent) {
+	    			return messageSentTimerWorker.getAverage();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CREATED :
+	    		if (profileSessionCreated) {
+	    			return sessionCreatedTimerWorker.getAverage();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_OPENED :
+	    		if (profileSessionOpened) {
+	    			return sessionOpenedTimerWorker.getAverage();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_IDLE :
+	    		if (profileSessionIdle) {
+	    			return sessionIdleTimerWorker.getAverage();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CLOSED :
+	    		if (profileSessionClosed) {
+	    			return sessionClosedTimerWorker.getAverage();
+	    		}
+	    		
+	    		break;
+    	}
 
-        return timerManager.get(type).getAverage();
+    	throw new IllegalArgumentException(
+                "You are not monitoring this event.  Please add this event first.");
     }
 
     /**
@@ -314,12 +547,52 @@
      *  The total number of method calls for the method represented by the {@link IoEventType}
      */
     public long getTotalCalls(IoEventType type) {
-        if (!timerManager.containsKey(type)) {
-            throw new IllegalArgumentException(
-                    "You are not monitoring this event.  Please add this event first.");
-        }
-
-        return timerManager.get(type).getCalls();
+    	switch (type) {
+	    	case MESSAGE_RECEIVED :
+	    		if (profileMessageReceived) {
+	    			return messageReceivedTimerWorker.getCallsNumber();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case MESSAGE_SENT :
+	    		if (profileMessageSent) {
+	    			return messageSentTimerWorker.getCallsNumber();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CREATED :
+	    		if (profileSessionCreated) {
+	    			return sessionCreatedTimerWorker.getCallsNumber();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_OPENED :
+	    		if (profileSessionOpened) {
+	    			return sessionOpenedTimerWorker.getCallsNumber();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_IDLE :
+	    		if (profileSessionIdle) {
+	    			return sessionIdleTimerWorker.getCallsNumber();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CLOSED :
+	    		if (profileSessionClosed) {
+	    			return sessionClosedTimerWorker.getCallsNumber();
+	    		}
+	    		
+	    		break;
+		}
+	
+		throw new IllegalArgumentException(
+	            "You are not monitoring this event.  Please add this event first.");
     }
 
     /**
@@ -332,12 +605,52 @@
      *  The total time for the method represented by the {@link IoEventType}
      */
     public long getTotalTime(IoEventType type) {
-        if (!timerManager.containsKey(type)) {
-            throw new IllegalArgumentException(
-                    "You are not monitoring this event.  Please add this event first.");
-        }
-
-        return timerManager.get(type).getTotal();
+    	switch (type) {
+	    	case MESSAGE_RECEIVED :
+	    		if (profileMessageReceived) {
+	    			return messageReceivedTimerWorker.getTotal();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case MESSAGE_SENT :
+	    		if (profileMessageSent) {
+	    			return messageSentTimerWorker.getTotal();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CREATED :
+	    		if (profileSessionCreated) {
+	    			return sessionCreatedTimerWorker.getTotal();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_OPENED :
+	    		if (profileSessionOpened) {
+	    			return sessionOpenedTimerWorker.getTotal();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_IDLE :
+	    		if (profileSessionIdle) {
+	    			return sessionIdleTimerWorker.getTotal();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CLOSED :
+	    		if (profileSessionClosed) {
+	    			return sessionClosedTimerWorker.getTotal();
+	    		}
+	    		
+	    		break;
+		}
+	
+		throw new IllegalArgumentException(
+	            "You are not monitoring this event.  Please add this event first.");
     }
 
     /**
@@ -350,12 +663,52 @@
      *  The minimum time this method has executed represented by the {@link IoEventType}
      */
     public long getMinimumTime(IoEventType type) {
-        if (!timerManager.containsKey(type)) {
-            throw new IllegalArgumentException(
-                    "You are not monitoring this event.  Please add this event first.");
-        }
-
-        return timerManager.get(type).getMinimum();
+    	switch (type) {
+	    	case MESSAGE_RECEIVED :
+	    		if (profileMessageReceived) {
+	    			return messageReceivedTimerWorker.getMinimum();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case MESSAGE_SENT :
+	    		if (profileMessageSent) {
+	    			return messageSentTimerWorker.getMinimum();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CREATED :
+	    		if (profileSessionCreated) {
+	    			return sessionCreatedTimerWorker.getMinimum();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_OPENED :
+	    		if (profileSessionOpened) {
+	    			return sessionOpenedTimerWorker.getMinimum();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_IDLE :
+	    		if (profileSessionIdle) {
+	    			return sessionIdleTimerWorker.getMinimum();
+	    		}
+	    		
+	    		break;
+	    		
+	    	case SESSION_CLOSED :
+	    		if (profileSessionClosed) {
+	    			return sessionClosedTimerWorker.getMinimum();
+	    		}
+	    		
+	    		break;
+		}
+	
+		throw new IllegalArgumentException(
+	            "You are not monitoring this event.  Please add this event first.");
     }
 
     /**
@@ -368,12 +721,52 @@
      *  The maximum time this method has executed represented by the {@link IoEventType}
      */
     public long getMaximumTime(IoEventType type) {
-        if (!timerManager.containsKey(type)) {
-            throw new IllegalArgumentException(
-                    "You are not monitoring this event.  Please add this event first.");
-        }
-
-        return timerManager.get(type).getMaximum();
+    	switch (type) {
+			case MESSAGE_RECEIVED :
+				if (profileMessageReceived) {
+					return messageReceivedTimerWorker.getMaximum();
+				}
+				
+				break;
+				
+			case MESSAGE_SENT :
+				if (profileMessageSent) {
+					return messageSentTimerWorker.getMaximum();
+				}
+				
+				break;
+				
+			case SESSION_CREATED :
+				if (profileSessionCreated) {
+					return sessionCreatedTimerWorker.getMaximum();
+				}
+				
+				break;
+				
+			case SESSION_OPENED :
+				if (profileSessionOpened) {
+					return sessionOpenedTimerWorker.getMaximum();
+				}
+				
+				break;
+				
+			case SESSION_IDLE :
+				if (profileSessionIdle) {
+					return sessionIdleTimerWorker.getMaximum();
+				}
+				
+				break;
+				
+			case SESSION_CLOSED :
+				if (profileSessionClosed) {
+					return sessionClosedTimerWorker.getMaximum();
+				}
+				
+				break;
+		}
+		
+		throw new IllegalArgumentException(
+		        "You are not monitoring this event.  Please add this event first.");
     }
 
     /**
@@ -382,11 +775,19 @@
      *
      */
     private class TimerWorker {
-
+    	/** The sum of all operation durations */
         private final AtomicLong total;
-        private final AtomicLong calls;
+        
+        /** The number of calls */
+        private final AtomicLong callsNumber;
+        
+        /** The fastest operation */
         private final AtomicLong minimum;
+        
+        /** The slowest operation */
         private final AtomicLong maximum;
+        
+        /** A lock for synchinized blocks */
         private final Object lock = new Object();
 
         /**
@@ -395,31 +796,31 @@
          */
         public TimerWorker() {
             total = new AtomicLong();
-            calls = new AtomicLong();
+            callsNumber = new AtomicLong();
             minimum = new AtomicLong();
             maximum = new AtomicLong();
         }
 
         /**
-         * Add a new reading to this class.  Total is updated
+         * Add a new operation duration to this class.  Total is updated
          * and calls is incremented
          *
-         * @param newReading
-         *  The new reading
+         * @param duration
+         *  The new operation duration
          */
-        public void addNewReading(long newReading) {
-            calls.incrementAndGet();
-            total.addAndGet(newReading);
+        public void addNewDuration(long duration) {
+        	callsNumber.incrementAndGet();
+            total.addAndGet(duration);
 
             synchronized (lock) {
                 // this is not entirely thread-safe, must lock
-                if (newReading < minimum.longValue()) {
-                    minimum.set(newReading);
+                if (duration < minimum.longValue()) {
+                    minimum.set(duration);
                 }
 
                 // this is not entirely thread-safe, must lock
-                if (newReading > maximum.longValue()) {
-                    maximum.set(newReading);
+                if (duration > maximum.longValue()) {
+                    maximum.set(duration);
                 }
             }
         }
@@ -427,106 +828,68 @@
         /**
          * Gets the average reading for this event
          *
-         * @return
-         *  Gets the average reading for this event
+         * @return the average reading for this event
          */
         public double getAverage() {
-            return total.longValue() / calls.longValue();
+        	synchronized (lock) {
+        		// There are two operations, we need to synchronize the block
+        		return total.longValue() / callsNumber.longValue();
+        	}
         }
 
         /**
-         * Returns the total number of readings
+         * Returns the total number of profiled operations
          *
-         * @return
-         *  total number of readings
+         * @return The total number of profiled operation 
          */
-        public long getCalls() {
-            return calls.longValue();
+        public long getCallsNumber() {
+            return callsNumber.longValue();
         }
 
         /**
          * Returns the total time
          *
-         * @return
-         *  the total time
+         * @return the total time
          */
         public long getTotal() {
             return total.longValue();
         }
 
         /**
-         * Returns the minimum value
+         * Returns the lowest execution time 
          *
-         * @return
-         *  the minimum value
+         * @return the lowest execution time
          */
         public long getMinimum() {
             return minimum.longValue();
         }
 
         /**
-         * Returns the maximum value
+         * Returns the longest execution time
          *
-         * @return
-         *  the maximum value
+         * @return the longest execution time
          */
         public long getMaximum() {
             return maximum.longValue();
         }
     }
 
-    private enum ProfilerTimerUnit {
-        SECONDS {
-            @Override
-            public long timeNow() {
-                return System.currentTimeMillis() / 1000;
-            }
-
-            @Override
-            public String getDescription() {
-                return "seconds";
-            }
-        },
-        MILLISECONDS {
-            @Override
-            public long timeNow() {
-                return System.currentTimeMillis();
-            }
-
-            @Override
-            public String getDescription() {
-                return "milliseconds";
-            }
-        },
-        NANOSECONDS {
-            @Override
-            public long timeNow() {
-                return System.nanoTime();
-            }
-
-            @Override
-            public String getDescription() {
-                return "nanoseconds";
-            }
-        };
-
-        /*
-         * I was looking at possibly using the java.util.concurrent.TimeUnit
-         * and I found this construct for writing enums.  Here is what the
-         * JDK developers say for why these methods below cannot be marked as
-         * abstract, but should act in an abstract way...
-         *
-         *     To maintain full signature compatibility with 1.5, and to improve the
-         *     clarity of the generated javadoc (see 6287639: Abstract methods in
-         *     enum classes should not be listed as abstract), method convert
-         *     etc. are not declared abstract but otherwise act as abstract methods.
-         */
-        public long timeNow() {
-            throw new AbstractMethodError();
-        }
-
-        public String getDescription() {
-            throw new AbstractMethodError();
-        }
+    /**
+     * @return the current time, expressed using the fixed TimeUnit.
+     */
+    private long timeNow() {
+    	switch (timeUnit) {
+	    	case SECONDS :
+	    		return System.currentTimeMillis()/1000;
+	    		
+	    	case MICROSECONDS :
+	    		return System.nanoTime()/1000;
+	    		
+	    	case NANOSECONDS :
+	    		return System.nanoTime();
+	    		
+	    	default :
+	    		return System.currentTimeMillis();
+    	}
     }
 }

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/util/ReferenceCountingFilter.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/util/ReferenceCountingFilter.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/util/ReferenceCountingFilter.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/util/ReferenceCountingFilter.java Sun Oct 19 12:40:20 2008
@@ -20,6 +20,7 @@
 package org.apache.mina.filter.util;
 
 import org.apache.mina.core.filterchain.IoFilter;
+import org.apache.mina.core.filterchain.IoFilterAdapter;
 import org.apache.mina.core.filterchain.IoFilterChain;
 import org.apache.mina.core.session.IdleStatus;
 import org.apache.mina.core.session.IoSession;
@@ -34,7 +35,7 @@
  * @version $Rev$, $Date$
  * @org.apache.xbean.XBean
  */
-public class ReferenceCountingFilter implements IoFilter {
+public class ReferenceCountingFilter extends IoFilterAdapter {
     private final IoFilter filter;
 
     private int count = 0;

Modified: mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java Sun Oct 19 12:40:20 2008
@@ -170,8 +170,8 @@
     }
 
     @Override
-    protected boolean select(int timeout) throws Exception {
-        return selector.select(timeout) > 0;
+    protected int select(int timeout) throws Exception {
+        return selector.select(timeout);
     }
 
     @Override

Modified: mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramConnector.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramConnector.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramConnector.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramConnector.java Sun Oct 19 12:40:20 2008
@@ -178,8 +178,8 @@
     }
 
     @Override
-    protected boolean select(int timeout) throws Exception {
-        return false;
+    protected int select(int timeout) throws Exception {
+        return 0;
     }
 
     @Override

Modified: mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java Sun Oct 19 12:40:20 2008
@@ -65,8 +65,8 @@
     }
 
     @Override
-    protected boolean select(int timeout) throws Exception {
-        return selector.select(timeout) > 0;
+    protected int select(int timeout) throws Exception {
+        return selector.select(timeout);
     }
 
     @Override

Modified: mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketAcceptor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketAcceptor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketAcceptor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketAcceptor.java Sun Oct 19 12:40:20 2008
@@ -20,6 +20,7 @@
 package org.apache.mina.transport.socket.nio;
 
 import java.net.InetSocketAddress;
+import java.net.ServerSocket;
 import java.net.SocketAddress;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
@@ -49,7 +50,12 @@
         extends AbstractPollingIoAcceptor<NioSession, ServerSocketChannel>
         implements SocketAcceptor {
 
+    /** 
+     * Define the number of socket that can wait to be accepted. Default
+     * to 50 (as in the SocketServer default).
+     */
     private int backlog = 50;
+
     private boolean reuseAddress = false;
 
     private volatile Selector selector;
@@ -203,6 +209,11 @@
             ServerSocketChannel handle) throws Exception {
 
         SelectionKey key = handle.keyFor(selector);
+        
+        if (!key.isValid()) {
+            return null;
+        }
+
         if (!key.isAcceptable()) {
             return null;
         }
@@ -222,25 +233,26 @@
     @Override
     protected ServerSocketChannel open(SocketAddress localAddress)
             throws Exception {
-        ServerSocketChannel c = ServerSocketChannel.open();
+        ServerSocketChannel channel = ServerSocketChannel.open();
         boolean success = false;
         try {
-            c.configureBlocking(false);
+            channel.configureBlocking(false);
             // Configure the server socket,
-            c.socket().setReuseAddress(isReuseAddress());
+            ServerSocket socket = channel.socket();
+            socket.setReuseAddress(isReuseAddress());
             // XXX: Do we need to provide this property? (I think we need to remove it.)
-            c.socket().setReceiveBufferSize(
-                    getSessionConfig().getReceiveBufferSize());
+            socket.setReceiveBufferSize(getSessionConfig().getReceiveBufferSize());
             // and bind.
-            c.socket().bind(localAddress, getBacklog());
-            c.register(selector, SelectionKey.OP_ACCEPT);
+            socket.bind(localAddress, getBacklog());
+            // Register the channel within the selector for ACCEPT event
+            channel.register(selector, SelectionKey.OP_ACCEPT);
             success = true;
         } finally {
             if (!success) {
-                close(c);
+                close(channel);
             }
         }
-        return c;
+        return channel;
     }
 
     /**
@@ -261,13 +273,13 @@
       * this selector's wakeup method is invoked, or the current thread 
       * is interrupted, whichever comes first.
       * 
-      * @return <code>true</code> if one key has its ready-operation set updated
+      * @return The number of keys having their ready-operation set updated
       * @throws IOException If an I/O error occurs
       * @throws ClosedSelectorException If this selector is closed 
       */
     @Override
-    protected boolean select() throws Exception {
-        return selector.select() > 0;
+    protected int select() throws Exception {
+        return selector.select();
     }
 
     /**
@@ -298,34 +310,54 @@
         selector.wakeup();
     }
 
+    /**
+     * Defines an iterator for the selected-key Set returned by the 
+     * selector.selectedKeys(). It replaces the SelectionKey operator.
+     */
     private static class ServerSocketChannelIterator implements Iterator<ServerSocketChannel> {
+        /** The selected-key iterator */
+        private final Iterator<SelectionKey> iterator;
 
-        private final Iterator<SelectionKey> i;
-
+        /**
+         * Build a SocketChannel iterator which will return a SocketChannel instead of
+         * a SelectionKey.
+         * 
+         * @param selectedKeys The selector selected-key set 
+         */
         private ServerSocketChannelIterator(Collection<SelectionKey> selectedKeys) {
-            i = selectedKeys.iterator();
+            iterator = selectedKeys.iterator();
         }
 
         /**
-         * {@inheritDoc}
+         * Tells if there are more SockectChannel left in the iterator
+         * @return <code>true</code> if there is at least one more 
+         * SockectChannel object to read
          */
         public boolean hasNext() {
-            return i.hasNext();
+            return iterator.hasNext();
         }
 
         /**
-         * {@inheritDoc}
+         * Get the next SocketChannel in the operator we have built from
+         * the selected-key et for this selector.
+         * 
+         * @return The next SocketChannel in the iterator
          */
         public ServerSocketChannel next() {
-            SelectionKey key = i.next();
-            return (ServerSocketChannel) key.channel();
+            SelectionKey key = iterator.next();
+            
+            if ( key.isValid() && key.isAcceptable() ) {
+                return (ServerSocketChannel) key.channel();
+            } else {
+                return null;
+            }
         }
 
         /**
-         * {@inheritDoc}
+         * Remove the current SocketChannel from the iterator 
          */
         public void remove() {
-            i.remove();
+            iterator.remove();
         }
     }
 }

Modified: mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketConnector.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketConnector.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketConnector.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketConnector.java Sun Oct 19 12:40:20 2008
@@ -271,8 +271,8 @@
      * {@inheritDoc}
      */
     @Override
-    protected boolean select(int timeout) throws Exception {
-        return selector.select(timeout) > 0;
+    protected int select(int timeout) throws Exception {
+        return selector.select(timeout);
     }
 
     /**

Modified: mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java
URL: http://svn.apache.org/viewvc/mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java (original)
+++ mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprIoProcessor.java Sun Oct 19 12:40:20 2008
@@ -125,7 +125,7 @@
     }
 
     @Override
-    protected boolean select(int timeout) throws Exception {
+    protected int select(int timeout) throws Exception {
         int rv = Poll.poll(pollset, 1000 * timeout, polledSockets, false);
         if (rv <= 0) {
             if (rv != -120001) {
@@ -150,7 +150,7 @@
                 throwException(rv);
             }
 
-            return false;
+            return 0;
         } else {
             rv <<= 1;
             if (!polledSessions.isEmpty()) {
@@ -177,7 +177,7 @@
                 polledSessions.add(session);
             }
 
-            return !polledSessions.isEmpty();
+            return polledSessions.size();
         }
     }
 

Modified: mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketAcceptor.java
URL: http://svn.apache.org/viewvc/mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketAcceptor.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketAcceptor.java (original)
+++ mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketAcceptor.java Sun Oct 19 12:40:20 2008
@@ -215,7 +215,7 @@
     }
 
     @Override
-    protected boolean select() throws Exception {
+    protected int select() throws Exception {
         int rv = Poll.poll(pollset, Integer.MAX_VALUE, polledSockets, false);
         if (rv <= 0) {
             // We have had an error. It can simply be that we have reached
@@ -234,7 +234,7 @@
                 throwException(rv);
             }
 
-            return false;
+            return 0;
         } else {
             rv <<= 1;
             if (!polledHandles.isEmpty()) {
@@ -256,7 +256,7 @@
                     polledHandles.add(socket);
                 }
             }
-            return !polledHandles.isEmpty();
+            return polledHandles.size();
         }
     }
 

Modified: mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketConnector.java
URL: http://svn.apache.org/viewvc/mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketConnector.java?rev=706057&r1=706056&r2=706057&view=diff
==============================================================================
--- mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketConnector.java (original)
+++ mina/trunk/transport-apr/src/main/java/org/apache/mina/transport/socket/apr/AprSocketConnector.java Sun Oct 19 12:40:20 2008
@@ -53,6 +53,12 @@
  */
 public final class AprSocketConnector extends AbstractPollingIoConnector<AprSession, Long> implements SocketConnector {
 
+    /** 
+     * This constant is deduced from the APR code. It is used when the timeout
+     * has expired while doing a poll() operation.
+     */ 
+    private static final int APR_TIMEUP_ERROR = -120001;
+
     private static final int POLLSET_SIZE = 1024;
 
     private final Map<Long, ConnectionRequest> requests =
@@ -299,10 +305,10 @@
      * {@inheritDoc}
      */
     @Override
-    protected boolean select(int timeout) throws Exception {
+    protected int select(int timeout) throws Exception {
         int rv = Poll.poll(pollset, timeout * 1000, polledSockets, false);
         if (rv <= 0) {
-            if (rv != -120001) {
+            if (rv != APR_TIMEUP_ERROR) {
                 throwException(rv);
             }
 
@@ -315,7 +321,7 @@
                 throwException(rv);
             }
 
-            return false;
+            return 0;
         } else {
             rv <<= 1;
             if (!polledHandles.isEmpty()) {
@@ -337,7 +343,7 @@
                     failedHandles.add(socket);
                 }
             }
-            return !polledHandles.isEmpty();
+            return polledHandles.size();
         }
     }