Author: fhanik Date: Thu Jul 13 20:27:06 2006 New Revision: 421791 URL: http://svn.apache.org/viewvc?rev=421791&view=rev Log: Optimize timeout handling, thanks to a suggestion from [EMAIL PROTECTED], although this does put a gap in the timeout check, even in those cases where there shouldn't be, ie, a socket can be closed immediately
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=421791&r1=421790&r2=421791&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Thu Jul 13 20:27:06 2006 @@ -572,21 +572,7 @@ boolean addToQueue = false; try { addToQueue = ((key.interestOps()&SelectionKey.OP_READ) != SelectionKey.OP_READ); } catch ( CancelledKeyException ignore ){} if ( addToQueue ) { - att.setWakeUp(true); - poller.addEvent( - new Runnable() { - public void run() { - try { - if (key != null) key.interestOps(SelectionKey.OP_READ); - } catch (CancelledKeyException ckx) { - try { - socket.socket().close(); - socket.close(); - att.setWakeUp(false); - } catch (Exception ignore) {} - } - } - }); + addToReadQueue(key, att); }//end if synchronized (att.getMutex()) { if ( att.getWakeUp() ) att.getMutex().wait(25); @@ -596,6 +582,28 @@ //else throw new IOException(sm.getString("iib.failedread")); //return false; //timeout throw new IOException("read timed out."); + } + + private void addToReadQueue(final SelectionKey key, final KeyAttachment att) { + att.setWakeUp(true); + poller.addEvent( + new Runnable() { + public void run() { + try { + if (key != null) key.interestOps(SelectionKey.OP_READ); + } catch (CancelledKeyException ckx) { + try { + if ( key != null && key.attachment() != null ) { + KeyAttachment ka = (KeyAttachment)key.attachment(); + ka.setError(true); //set to collect this socket immediately + } + socket.socket().close(); + socket.close(); + att.setWakeUp(false); + } catch (Exception ignore) {} + } + } + }); } Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=421791&r1=421790&r2=421791&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Thu Jul 13 20:27:06 2006 @@ -967,6 +967,7 @@ protected Selector selector; protected LinkedList<Runnable> events = new LinkedList<Runnable>(); protected boolean close = false; + protected long nextExpiration = 0;//optimize expiration handling protected int keepAliveCount = 0; public int getKeepAliveCount() { return keepAliveCount; } @@ -1029,6 +1030,10 @@ if (key != null) key.interestOps(SelectionKey.OP_READ); }catch ( CancelledKeyException ckx ) { try { + if ( key != null && key.attachment() != null ) { + KeyAttachment ka = (KeyAttachment)key.attachment(); + ka.setError(true); //set to collect this socket immediately + } socket.socket().close(); socket.close(); } catch ( Exception ignore ) {} @@ -1075,7 +1080,7 @@ try { KeyAttachment ka = (KeyAttachment) key.attachment(); key.cancel(); - if (ka.getComet()) processSocket( (SocketChannel) key.channel(), true); + if (ka != null && ka.getComet()) processSocket( (SocketChannel) key.channel(), true); key.channel().close(); } catch (IOException e) { if ( log.isDebugEnabled() ) log.debug("",e); @@ -1156,34 +1161,45 @@ log.error("",t); } }//while - - //timeout - Set<SelectionKey> keys = selector.keys(); - long now = System.currentTimeMillis(); - for (Iterator<SelectionKey> iter = keys.iterator(); iter.hasNext(); ) { - SelectionKey key = iter.next(); - try { - if (key.interestOps() == SelectionKey.OP_READ) { - //only timeout sockets that we are waiting for a read from - KeyAttachment ka = (KeyAttachment) key.attachment(); - long delta = now - ka.getLastAccess(); - boolean isTimedout = (ka.getTimeout()==-1)?(delta > (long) soTimeout):(delta>ka.getTimeout()); - if (isTimedout) { - cancelledKey(key); - } - } - }catch ( CancelledKeyException ckx ) { - cancelledKey(key); - } - } - + //process timeouts + timeout(); } synchronized (this) { this.notifyAll(); } } - + protected void timeout() { + long now = System.currentTimeMillis(); + if ( now < nextExpiration ) return; + nextExpiration = now + (long)soTimeout; + //timeout + Set<SelectionKey> keys = selector.keys(); + for (Iterator<SelectionKey> iter = keys.iterator(); iter.hasNext(); ) { + SelectionKey key = iter.next(); + try { + KeyAttachment ka = (KeyAttachment) key.attachment(); + if ( ka == null ) { + cancelledKey(key); //we don't support any keys without attachments + } else if ( ka.getError() ) { + cancelledKey(key); + }else if ((key.interestOps()&SelectionKey.OP_READ) == SelectionKey.OP_READ) { + //only timeout sockets that we are waiting for a read from + long delta = now - ka.getLastAccess(); + long timeout = (ka.getTimeout()==-1)?((long) soTimeout):(ka.getTimeout()); + boolean isTimedout = delta > timeout; + if (isTimedout) { + cancelledKey(key); + } else { + long nextTime = now+(timeout-delta); + nextExpiration = (nextTime < nextExpiration)?nextTime:nextExpiration; + } + }//end if + }catch ( CancelledKeyException ckx ) { + cancelledKey(key); + } + }//for + } } public static class KeyAttachment { @@ -1200,12 +1216,15 @@ public Object getMutex() {return mutex;} public void setTimeout(long timeout) {this.timeout = timeout;} public long getTimeout() {return this.timeout;} + public boolean getError() { return error; } + public void setError(boolean error) { this.error = error; } protected Object mutex = new Object(); protected boolean wakeUp = false; protected long lastAccess = System.currentTimeMillis(); protected boolean currentAccess = false; protected boolean comet = false; protected long timeout = -1; + protected boolean error = false; } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]