From e3b18108b645022d80c12ab0d416e3ac48d66ba0 Mon Sep 17 00:00:00 2001 From: fhanik Date: Sun, 8 Apr 2007 17:03:21 +0000 Subject: [PATCH] Start preparing for non blocking writes, the underlying code has to have the ability if there is ever gonna be a need fix NPE git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@526577 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/tomcat/util/net/NioEndpoint.java | 10 ++++-- .../apache/tomcat/util/net/NioSelectorPool.java | 42 +++++++++++++++++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java index 39762b554..34716c5fc 100644 --- a/java/org/apache/tomcat/util/net/NioEndpoint.java +++ b/java/org/apache/tomcat/util/net/NioEndpoint.java @@ -2063,8 +2063,9 @@ public class NioEndpoint { try { key = socket.getIOChannel().keyFor(socket.getPoller().getSelector()); int handshake = -1; + try { - handshake = socket.handshake(key.isReadable(), key.isWritable()); + if (key!=null) handshake = socket.handshake(key.isReadable(), key.isWritable()); }catch ( IOException x ) { handshake = -1; if ( log.isDebugEnabled() ) log.debug("Error during SSL handshake",x); @@ -2091,8 +2092,11 @@ public class NioEndpoint { } } } else if (handshake == -1 ) { - KeyAttachment ka = (KeyAttachment)key.attachment(); - socket.getPoller().cancelledKey(key,SocketStatus.DISCONNECT,false); + KeyAttachment ka = null; + if (key!=null) { + ka = (KeyAttachment) key.attachment(); + socket.getPoller().cancelledKey(key, SocketStatus.DISCONNECT, false); + } try {socket.close(true);}catch (IOException ignore){} nioChannels.offer(socket); if ( ka!=null ) keyCache.offer(ka); diff --git a/java/org/apache/tomcat/util/net/NioSelectorPool.java b/java/org/apache/tomcat/util/net/NioSelectorPool.java index 8b6c206fb..0910d919e 100644 --- a/java/org/apache/tomcat/util/net/NioSelectorPool.java +++ b/java/org/apache/tomcat/util/net/NioSelectorPool.java @@ -126,7 +126,11 @@ public class NioSelectorPool { * @throws IOException if an IO Exception occurs in the underlying socket logic */ public int write(ByteBuffer buf, NioChannel socket, Selector selector, long writeTimeout) throws IOException { - if ( SHARED ) { + return write(buf,socket,selector,writeTimeout,true); + } + + public int write(ByteBuffer buf, NioChannel socket, Selector selector, long writeTimeout, boolean block) throws IOException { + if ( SHARED && block) { return NioBlockingSelector.write(buf,socket,writeTimeout); } SelectionKey key = null; @@ -140,14 +144,16 @@ public class NioSelectorPool { } try { while ( (!timedout) && buf.hasRemaining() ) { + int cnt = 0; if ( keycount > 0 ) { //only write if we were registered for a write - int cnt = socket.write(buf); //write the data + cnt = socket.write(buf); //write the data if (cnt == -1) throw new EOFException(); written += cnt; if (cnt > 0) { time = System.currentTimeMillis(); //reset our timeout timer continue; //we successfully wrote, try again without a selector } + if (cnt==0 && (!block)) break; //don't block } if ( selector != null ) { //register OP_WRITE to the selector @@ -181,7 +187,25 @@ public class NioSelectorPool { * @throws IOException if an IO Exception occurs in the underlying socket logic */ public int read(ByteBuffer buf, NioChannel socket, Selector selector, long readTimeout) throws IOException { - if ( SHARED ) { + return read(buf,socket,selector,readTimeout,true); + } + /** + * Performs a read using the bytebuffer for data to be read and a selector to register for events should + * you have the block=true. + * If the selector parameter is null, then it will perform a busy read that could + * take up a lot of CPU cycles. + * @param buf ByteBuffer - the buffer containing the data, we will read as until we have read at least one byte or we timed out + * @param socket SocketChannel - the socket to write data to + * @param selector Selector - the selector to use for blocking, if null then a busy read will be initiated + * @param readTimeout long - the timeout for this read operation in milliseconds, -1 means no timeout + * @param block - true if you want to block until data becomes available or timeout time has been reached + * @return int - returns the number of bytes read + * @throws EOFException if read returns -1 + * @throws SocketTimeoutException if the read times out + * @throws IOException if an IO Exception occurs in the underlying socket logic + */ + public int read(ByteBuffer buf, NioChannel socket, Selector selector, long readTimeout, boolean block) throws IOException { + if ( SHARED && block) { return NioBlockingSelector.read(buf,socket,readTimeout); } SelectionKey key = null; @@ -190,14 +214,16 @@ public class NioSelectorPool { int keycount = 1; //assume we can write long time = System.currentTimeMillis(); //start the timeout timer try { - while ( (!timedout) && read == 0 ) { + while ( (!timedout) ) { + int cnt = 0; if ( keycount > 0 ) { //only read if we were registered for a read - int cnt = socket.read(buf); + cnt = socket.read(buf); if (cnt == -1) throw new EOFException(); read += cnt; - if (cnt > 0) break; - } - if ( selector != null ) { + if (cnt > 0) continue; //read some more + if (cnt==0 && (read>0 || (!block) ) ) break; //we are done reading + } + if ( selector != null ) {//perform a blocking read //register OP_WRITE to the selector if (key==null) key = socket.getIOChannel().register(selector, SelectionKey.OP_READ); else key.interestOps(SelectionKey.OP_READ); -- 2.11.0