Improve poller timeout handling to not waste cycles
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 6 Aug 2007 23:19:37 +0000 (23:19 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 6 Aug 2007 23:19:37 +0000 (23:19 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@563331 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/tomcat/util/net/NioEndpoint.java
java/org/apache/tomcat/util/net/SocketProperties.java

index dfa74a4..ebc76de 100644 (file)
@@ -1582,8 +1582,11 @@ public class NioEndpoint {
             long now = System.currentTimeMillis();
             //don't process timeouts too frequently, but if the selector simply timed out
             //then we can check timeouts to avoid gaps
-            if ( (now < nextExpiration) && (keyCount>0 || hasEvents) && (!close) ) return;
-            nextExpiration = now + (long)socketProperties.getSoTimeout();
+            if ( ((keyCount>0 || hasEvents) ||(now < nextExpiration)) && (!close) ) {
+                return;
+            }
+            long prevExp = nextExpiration;
+            nextExpiration = now + socketProperties.getTimeoutInterval();
             //timeout
             Set<SelectionKey> keys = selector.keys();
             int keycount = 0;
@@ -1618,7 +1621,9 @@ public class NioEndpoint {
                     cancelledKey(key, SocketStatus.ERROR,false);
                 }
             }//for
-            if ( log.isDebugEnabled() ) log.debug("Poller processed "+keycount+" keys through timeout");
+           if ( log.isDebugEnabled() ) log.debug("timeout completed: keycount="+keycount+"; now="+now+"; nextExpiration="+prevExp+"; "+
+                                                  "keyCount="+keyCount+"; hasEvents="+hasEvents +"; eval="+( (now < prevExp) && (keyCount>0 || hasEvents) && (!close) ));
+
         }
     }
 
index 7a50135..c1cdf84 100644 (file)
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.util.net;
-
-import java.net.Socket;
-import java.net.SocketException;
-/**
- * Properties that can be set in the &lt;Connector&gt; element
- * in server.xml. All properties are prefixed with &quot;socket.&quot;
- * and are currently only working for the Nio connector
- *
- * @author Filip Hanik
- */
-public class SocketProperties {
-    /**
-     * Enable/disable key cache, this bounded cache stores
-     * KeyAttachment objects to reduce GC
-     * Default is 500
-     * -1 is unlimited
-     * 0 is disabled
-     */
-    protected int keyCache = 500;
-    
-    /**
-     * Enable/disable socket processor cache, this bounded cache stores
-     * SocketProcessor objects to reduce GC
-     * Default is 500
-     * -1 is unlimited
-     * 0 is disabled
-     */
-    protected int processorCache = 500;
-
-
-
-    /**
-     * Enable/disable poller event cache, this bounded cache stores
-     * PollerEvent objects to reduce GC for the poller
-     * Default is 500 
-     * -1 is unlimited
-     * 0 is disabled
-     * >0 the max number of objects to keep in cache.
-     */
-    protected int eventCache = 500;
-
-
-    /**
-     * Enable/disable direct buffers for the network buffers
-     * Default value is enabled
-     */
-    protected boolean directBuffer = false;
-    /**
-     * Socket receive buffer size in bytes (SO_RCVBUF)
-     * Default value is 25188
-     */
-    protected int rxBufSize = 25188;
-    /**
-     * Socket send buffer size in bytes (SO_SNDBUF)
-     * Default value is 43800
-     */
-    protected int txBufSize = 43800;
-
-    /**
-     * The application read buffer size in bytes.
-     * Default value is rxBufSize
-     */
-    protected int appReadBufSize = 8192;
-
-    /**
-     * The application write buffer size in bytes
-     * Default value is txBufSize
-     */
-    protected int appWriteBufSize = 8192;
-
-    /**
-     * NioChannel pool size for the endpoint,
-     * this value is how many channels
-     * -1 means unlimited cached, 0 means no cache
-     * Default value is 500
-     */
-    protected int bufferPool = 500;
-
-
-    /**
-     * Buffer pool size in bytes to be cached
-     * -1 means unlimited, 0 means no cache
-     * Default value is 100MB (1024*1024*100 bytes)
-     */
-    protected int bufferPoolSize = 1024*1024*100;
-
-    /**
-     * TCP_NO_DELAY option, default is true
-     */
-    protected boolean tcpNoDelay = true;
-    /**
-     * SO_KEEPALIVE option, default is false
-     */
-    protected boolean soKeepAlive = false;
-    /**
-     * OOBINLINE option, default is true
-     */
-    protected boolean ooBInline = true;
-    /**
-     * SO_REUSEADDR option, default is true
-     */
-    protected boolean soReuseAddress = true;
-    /**
-     * SO_LINGER option, default is true, paired with the <code>soLingerTime</code> value
-     */
-    protected boolean soLingerOn = true;
-    /**
-     * SO_LINGER option, default is 25 seconds.
-     */
-    protected int soLingerTime = 25;
-    /**
-     * SO_TIMEOUT option, default is 5000 milliseconds
-     */
-    protected int soTimeout = 5000;
-    /**
-     * Traffic class option, value between 0 and 255
-     * IPTOS_LOWCOST (0x02)
-     * IPTOS_RELIABILITY (0x04)
-     * IPTOS_THROUGHPUT (0x08)
-     * IPTOS_LOWDELAY (0x10)
-     * Default value is 0x04 | 0x08 | 0x010
-     */
-    protected int soTrafficClass = 0x04 | 0x08 | 0x010;
-    /**
-     * Performance preferences according to
-     * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
-     * Default value is 1
-     */
-    protected int performanceConnectionTime = 1;
-    /**
-     * Performance preferences according to
-     * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
-     * Default value is 0
-     */
-    protected int performanceLatency = 0;
-    /**
-     * Performance preferences according to
-     * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
-     * Default value is 1
-     */
-    protected int performanceBandwidth = 1;
-    private Socket properties;
-
-    public void setProperties(Socket socket) throws SocketException{
-        socket.setReceiveBufferSize(rxBufSize);
-        socket.setSendBufferSize(txBufSize);
-        socket.setOOBInline(ooBInline);
-        socket.setKeepAlive(soKeepAlive);
-        socket.setPerformancePreferences(performanceConnectionTime,performanceLatency,performanceBandwidth);
-        socket.setReuseAddress(soReuseAddress);
-        socket.setSoLinger(soLingerOn,soLingerTime);
-        socket.setSoTimeout(soTimeout);
-        socket.setTcpNoDelay(tcpNoDelay);
-        socket.setTrafficClass(soTrafficClass);
-    }
-
-    public boolean getDirectBuffer() {
-        return directBuffer;
-    }
-
-    public boolean getOoBInline() {
-        return ooBInline;
-    }
-
-    public int getPerformanceBandwidth() {
-        return performanceBandwidth;
-    }
-
-    public int getPerformanceConnectionTime() {
-        return performanceConnectionTime;
-    }
-
-    public int getPerformanceLatency() {
-        return performanceLatency;
-    }
-
-    public int getRxBufSize() {
-        return rxBufSize;
-    }
-
-    public boolean getSoKeepAlive() {
-        return soKeepAlive;
-    }
-
-    public boolean getSoLingerOn() {
-        return soLingerOn;
-    }
-
-    public int getSoLingerTime() {
-        return soLingerTime;
-    }
-
-    public boolean getSoReuseAddress() {
-        return soReuseAddress;
-    }
-
-    public int getSoTimeout() {
-        return soTimeout;
-    }
-
-    public int getSoTrafficClass() {
-        return soTrafficClass;
-    }
-
-    public boolean getTcpNoDelay() {
-        return tcpNoDelay;
-    }
-
-    public int getTxBufSize() {
-        return txBufSize;
-    }
-
-    public int getBufferPool() {
-        return bufferPool;
-    }
-
-    public int getBufferPoolSize() {
-        return bufferPoolSize;
-    }
-
-    public int getEventCache() {
-        return eventCache;
-    }
-
-    public int getKeyCache() {
-        return keyCache;
-    }
-
-    public Socket getProperties() {
-        return properties;
-    }
-
-    public int getAppReadBufSize() {
-        return appReadBufSize;
-    }
-
-    public int getAppWriteBufSize() {
-        return appWriteBufSize;
-    }
-
-    public int getProcessorCache() {
-        return processorCache;
-    }
-
-    public int getDirectBufferPool() {
-        return bufferPool;
-    }
-
-    public void setPerformanceConnectionTime(int performanceConnectionTime) {
-        this.performanceConnectionTime = performanceConnectionTime;
-    }
-
-    public void setTxBufSize(int txBufSize) {
-        this.txBufSize = txBufSize;
-    }
-
-    public void setTcpNoDelay(boolean tcpNoDelay) {
-        this.tcpNoDelay = tcpNoDelay;
-    }
-
-    public void setSoTrafficClass(int soTrafficClass) {
-        this.soTrafficClass = soTrafficClass;
-    }
-
-    public void setSoTimeout(int soTimeout) {
-        this.soTimeout = soTimeout;
-    }
-
-    public void setSoReuseAddress(boolean soReuseAddress) {
-        this.soReuseAddress = soReuseAddress;
-    }
-
-    public void setSoLingerTime(int soLingerTime) {
-        this.soLingerTime = soLingerTime;
-    }
-
-    public void setSoKeepAlive(boolean soKeepAlive) {
-        this.soKeepAlive = soKeepAlive;
-    }
-
-    public void setRxBufSize(int rxBufSize) {
-        this.rxBufSize = rxBufSize;
-    }
-
-    public void setPerformanceLatency(int performanceLatency) {
-        this.performanceLatency = performanceLatency;
-    }
-
-    public void setPerformanceBandwidth(int performanceBandwidth) {
-        this.performanceBandwidth = performanceBandwidth;
-    }
-
-    public void setOoBInline(boolean ooBInline) {
-        this.ooBInline = ooBInline;
-    }
-
-    public void setDirectBuffer(boolean directBuffer) {
-        this.directBuffer = directBuffer;
-    }
-
-    public void setSoLingerOn(boolean soLingerOn) {
-        this.soLingerOn = soLingerOn;
-    }
-
-    public void setBufferPool(int bufferPool) {
-        this.bufferPool = bufferPool;
-    }
-
-    public void setBufferPoolSize(int bufferPoolSize) {
-        this.bufferPoolSize = bufferPoolSize;
-    }
-
-    public void setEventCache(int eventCache) {
-        this.eventCache = eventCache;
-    }
-
-    public void setKeyCache(int keyCache) {
-        this.keyCache = keyCache;
-    }
-
-    public void setAppReadBufSize(int appReadBufSize) {
-        this.appReadBufSize = appReadBufSize;
-    }
-
-    public void setAppWriteBufSize(int appWriteBufSize) {
-        this.appWriteBufSize = appWriteBufSize;
-    }
-
-    public void setProcessorCache(int processorCache) {
-        this.processorCache = processorCache;
-    }
-
-    public void setDirectBufferPool(int directBufferPool) {
-        this.bufferPool = directBufferPool;
-    }
-
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.util.net;\r
+\r
+import java.net.Socket;\r
+import java.net.SocketException;\r
+/**\r
+ * Properties that can be set in the &lt;Connector&gt; element\r
+ * in server.xml. All properties are prefixed with &quot;socket.&quot;\r
+ * and are currently only working for the Nio connector\r
+ *\r
+ * @author Filip Hanik\r
+ */\r
+public class SocketProperties {\r
+    /**\r
+     * Enable/disable key cache, this bounded cache stores\r
+     * KeyAttachment objects to reduce GC\r
+     * Default is 500\r
+     * -1 is unlimited\r
+     * 0 is disabled\r
+     */\r
+    protected int keyCache = 500;\r
+    \r
+    /**\r
+     * Enable/disable socket processor cache, this bounded cache stores\r
+     * SocketProcessor objects to reduce GC\r
+     * Default is 500\r
+     * -1 is unlimited\r
+     * 0 is disabled\r
+     */\r
+    protected int processorCache = 500;\r
+\r
+\r
+\r
+    /**\r
+     * Enable/disable poller event cache, this bounded cache stores\r
+     * PollerEvent objects to reduce GC for the poller\r
+     * Default is 500 \r
+     * -1 is unlimited\r
+     * 0 is disabled\r
+     * >0 the max number of objects to keep in cache.\r
+     */\r
+    protected int eventCache = 500;\r
+\r
+\r
+    /**\r
+     * Enable/disable direct buffers for the network buffers\r
+     * Default value is enabled\r
+     */\r
+    protected boolean directBuffer = false;\r
+    /**\r
+     * Socket receive buffer size in bytes (SO_RCVBUF)\r
+     * Default value is 25188\r
+     */\r
+    protected int rxBufSize = 25188;\r
+    /**\r
+     * Socket send buffer size in bytes (SO_SNDBUF)\r
+     * Default value is 43800\r
+     */\r
+    protected int txBufSize = 43800;\r
+\r
+    /**\r
+     * The application read buffer size in bytes.\r
+     * Default value is rxBufSize\r
+     */\r
+    protected int appReadBufSize = 8192;\r
+\r
+    /**\r
+     * The application write buffer size in bytes\r
+     * Default value is txBufSize\r
+     */\r
+    protected int appWriteBufSize = 8192;\r
+\r
+    /**\r
+     * NioChannel pool size for the endpoint,\r
+     * this value is how many channels\r
+     * -1 means unlimited cached, 0 means no cache\r
+     * Default value is 500\r
+     */\r
+    protected int bufferPool = 500;\r
+\r
+\r
+    /**\r
+     * Buffer pool size in bytes to be cached\r
+     * -1 means unlimited, 0 means no cache\r
+     * Default value is 100MB (1024*1024*100 bytes)\r
+     */\r
+    protected int bufferPoolSize = 1024*1024*100;\r
+\r
+    /**\r
+     * TCP_NO_DELAY option, default is true\r
+     */\r
+    protected boolean tcpNoDelay = true;\r
+    /**\r
+     * SO_KEEPALIVE option, default is false\r
+     */\r
+    protected boolean soKeepAlive = false;\r
+    /**\r
+     * OOBINLINE option, default is true\r
+     */\r
+    protected boolean ooBInline = true;\r
+    /**\r
+     * SO_REUSEADDR option, default is true\r
+     */\r
+    protected boolean soReuseAddress = true;\r
+    /**\r
+     * SO_LINGER option, default is true, paired with the <code>soLingerTime</code> value\r
+     */\r
+    protected boolean soLingerOn = true;\r
+    /**\r
+     * SO_LINGER option, default is 25 seconds.\r
+     */\r
+    protected int soLingerTime = 25;\r
+    /**\r
+     * SO_TIMEOUT option, default is 5000 milliseconds\r
+     */\r
+    protected int soTimeout = 5000;\r
+    /**\r
+     * Traffic class option, value between 0 and 255\r
+     * IPTOS_LOWCOST (0x02)\r
+     * IPTOS_RELIABILITY (0x04)\r
+     * IPTOS_THROUGHPUT (0x08)\r
+     * IPTOS_LOWDELAY (0x10)\r
+     * Default value is 0x04 | 0x08 | 0x010\r
+     */\r
+    protected int soTrafficClass = 0x04 | 0x08 | 0x010;\r
+    /**\r
+     * Performance preferences according to\r
+     * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)\r
+     * Default value is 1\r
+     */\r
+    protected int performanceConnectionTime = 1;\r
+    /**\r
+     * Performance preferences according to\r
+     * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)\r
+     * Default value is 0\r
+     */\r
+    protected int performanceLatency = 0;\r
+    /**\r
+     * Performance preferences according to\r
+     * http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)\r
+     * Default value is 1\r
+     */\r
+    protected int performanceBandwidth = 1;\r
+    \r
+    /**\r
+     * The minimum frequency of the timeout interval to avoid the \r
+     * poller going boinkers during high traffic\r
+     */\r
+    protected long timeoutInterval = 1000;\r
+\r
+\r
+    private Socket properties;\r
+\r
+    public void setProperties(Socket socket) throws SocketException{\r
+        socket.setReceiveBufferSize(rxBufSize);\r
+        socket.setSendBufferSize(txBufSize);\r
+        socket.setOOBInline(ooBInline);\r
+        socket.setKeepAlive(soKeepAlive);\r
+        socket.setPerformancePreferences(performanceConnectionTime,performanceLatency,performanceBandwidth);\r
+        socket.setReuseAddress(soReuseAddress);\r
+        socket.setSoLinger(soLingerOn,soLingerTime);\r
+        socket.setSoTimeout(soTimeout);\r
+        socket.setTcpNoDelay(tcpNoDelay);\r
+        socket.setTrafficClass(soTrafficClass);\r
+    }\r
+\r
+    public boolean getDirectBuffer() {\r
+        return directBuffer;\r
+    }\r
+\r
+    public boolean getOoBInline() {\r
+        return ooBInline;\r
+    }\r
+\r
+    public int getPerformanceBandwidth() {\r
+        return performanceBandwidth;\r
+    }\r
+\r
+    public int getPerformanceConnectionTime() {\r
+        return performanceConnectionTime;\r
+    }\r
+\r
+    public int getPerformanceLatency() {\r
+        return performanceLatency;\r
+    }\r
+\r
+    public int getRxBufSize() {\r
+        return rxBufSize;\r
+    }\r
+\r
+    public boolean getSoKeepAlive() {\r
+        return soKeepAlive;\r
+    }\r
+\r
+    public boolean getSoLingerOn() {\r
+        return soLingerOn;\r
+    }\r
+\r
+    public int getSoLingerTime() {\r
+        return soLingerTime;\r
+    }\r
+\r
+    public boolean getSoReuseAddress() {\r
+        return soReuseAddress;\r
+    }\r
+\r
+    public int getSoTimeout() {\r
+        return soTimeout;\r
+    }\r
+\r
+    public int getSoTrafficClass() {\r
+        return soTrafficClass;\r
+    }\r
+\r
+    public boolean getTcpNoDelay() {\r
+        return tcpNoDelay;\r
+    }\r
+\r
+    public int getTxBufSize() {\r
+        return txBufSize;\r
+    }\r
+\r
+    public int getBufferPool() {\r
+        return bufferPool;\r
+    }\r
+\r
+    public int getBufferPoolSize() {\r
+        return bufferPoolSize;\r
+    }\r
+\r
+    public int getEventCache() {\r
+        return eventCache;\r
+    }\r
+\r
+    public int getKeyCache() {\r
+        return keyCache;\r
+    }\r
+\r
+    public Socket getProperties() {\r
+        return properties;\r
+    }\r
+\r
+    public int getAppReadBufSize() {\r
+        return appReadBufSize;\r
+    }\r
+\r
+    public int getAppWriteBufSize() {\r
+        return appWriteBufSize;\r
+    }\r
+\r
+    public int getProcessorCache() {\r
+        return processorCache;\r
+    }\r
+\r
+    public long getTimeoutInterval() {\r
+        return timeoutInterval;\r
+    }\r
+\r
+    public int getDirectBufferPool() {\r
+        return bufferPool;\r
+    }\r
+\r
+    public void setPerformanceConnectionTime(int performanceConnectionTime) {\r
+        this.performanceConnectionTime = performanceConnectionTime;\r
+    }\r
+\r
+    public void setTxBufSize(int txBufSize) {\r
+        this.txBufSize = txBufSize;\r
+    }\r
+\r
+    public void setTcpNoDelay(boolean tcpNoDelay) {\r
+        this.tcpNoDelay = tcpNoDelay;\r
+    }\r
+\r
+    public void setSoTrafficClass(int soTrafficClass) {\r
+        this.soTrafficClass = soTrafficClass;\r
+    }\r
+\r
+    public void setSoTimeout(int soTimeout) {\r
+        this.soTimeout = soTimeout;\r
+    }\r
+\r
+    public void setSoReuseAddress(boolean soReuseAddress) {\r
+        this.soReuseAddress = soReuseAddress;\r
+    }\r
+\r
+    public void setSoLingerTime(int soLingerTime) {\r
+        this.soLingerTime = soLingerTime;\r
+    }\r
+\r
+    public void setSoKeepAlive(boolean soKeepAlive) {\r
+        this.soKeepAlive = soKeepAlive;\r
+    }\r
+\r
+    public void setRxBufSize(int rxBufSize) {\r
+        this.rxBufSize = rxBufSize;\r
+    }\r
+\r
+    public void setPerformanceLatency(int performanceLatency) {\r
+        this.performanceLatency = performanceLatency;\r
+    }\r
+\r
+    public void setPerformanceBandwidth(int performanceBandwidth) {\r
+        this.performanceBandwidth = performanceBandwidth;\r
+    }\r
+\r
+    public void setOoBInline(boolean ooBInline) {\r
+        this.ooBInline = ooBInline;\r
+    }\r
+\r
+    public void setDirectBuffer(boolean directBuffer) {\r
+        this.directBuffer = directBuffer;\r
+    }\r
+\r
+    public void setSoLingerOn(boolean soLingerOn) {\r
+        this.soLingerOn = soLingerOn;\r
+    }\r
+\r
+    public void setBufferPool(int bufferPool) {\r
+        this.bufferPool = bufferPool;\r
+    }\r
+\r
+    public void setBufferPoolSize(int bufferPoolSize) {\r
+        this.bufferPoolSize = bufferPoolSize;\r
+    }\r
+\r
+    public void setEventCache(int eventCache) {\r
+        this.eventCache = eventCache;\r
+    }\r
+\r
+    public void setKeyCache(int keyCache) {\r
+        this.keyCache = keyCache;\r
+    }\r
+\r
+    public void setAppReadBufSize(int appReadBufSize) {\r
+        this.appReadBufSize = appReadBufSize;\r
+    }\r
+\r
+    public void setAppWriteBufSize(int appWriteBufSize) {\r
+        this.appWriteBufSize = appWriteBufSize;\r
+    }\r
+\r
+    public void setProcessorCache(int processorCache) {\r
+        this.processorCache = processorCache;\r
+    }\r
+\r
+    public void setTimeoutInterval(long timeoutInterval) {\r
+        this.timeoutInterval = timeoutInterval;\r
+    }\r
+\r
+    public void setDirectBufferPool(int directBufferPool) {\r
+        this.bufferPool = directBufferPool;\r
+    }\r
+\r
 }
\ No newline at end of file