Author: violetagg Date: Sat Aug 27 16:46:27 2016 New Revision: 1758058 URL: http://svn.apache.org/viewvc?rev=1758058&view=rev Log: Introduce a new method SocketWrapperBase.read(boolean, ByteBuffer)
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1758058&r1=1758057&r2=1758058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Sat Aug 27 16:46:27 2016 @@ -2306,6 +2306,42 @@ public class AprEndpoint extends Abstrac } + @Override + public int read(boolean block, ByteBuffer to) throws IOException { + int nRead = populateReadBuffer(to); + if (nRead > 0) { + to.flip(); + return nRead; + /* + * Since more bytes may have arrived since the buffer was last + * filled, it is an option at this point to perform a + * non-blocking read. However correctly handling the case if + * that read returns end of stream adds complexity. Therefore, + * at the moment, the preference is for simplicity. + */ + } + + // The socket read buffer capacity is socket.appReadBufSize + int limit = socketBufferHandler.getReadBuffer().capacity(); + if (to.remaining() >= limit) { + to.limit(to.position() + limit); + nRead = fillReadBuffer(block, to); + to.flip(); + } else { + // Fill the read buffer as best we can. + nRead = fillReadBuffer(block); + + // Fill as much of the remaining byte array as possible with the + // data that was just read + if (nRead > 0) { + nRead = populateReadBuffer(to); + to.flip(); + } + } + return nRead; + } + + private int fillReadBuffer(boolean block) throws IOException { socketBufferHandler.configureReadBufferForWrite(); return fillReadBuffer(block, socketBufferHandler.getReadBuffer()); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1758058&r1=1758057&r2=1758058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Sat Aug 27 16:46:27 2016 @@ -871,6 +871,66 @@ public class Nio2Endpoint extends Abstra @Override + public int read(boolean block, ByteBuffer to) throws IOException { + checkError(); + + if (socketBufferHandler == null) { + throw new IOException(sm.getString("socket.closed")); + } + + if (block) { + try { + readPending.acquire(); + } catch (InterruptedException e) { + throw new IOException(e); + } + } else { + if (!readPending.tryAcquire()) { + if (log.isDebugEnabled()) { + log.debug("Socket: [" + this + "], Read in progress. Returning [0]"); + } + return 0; + } + } + + int nRead = populateReadBuffer(to); + if (nRead > 0) { + // This may be sufficient to complete the request and we + // don't want to trigger another read since if there is no + // more data to read and this request takes a while to + // process the read will timeout triggering an error. + to.flip(); + readPending.release(); + return nRead; + } + + synchronized (readCompletionHandler) { + // The socket read buffer capacity is socket.appReadBufSize + int limit = socketBufferHandler.getReadBuffer().capacity(); + if (block && to.remaining() >= limit) { + to.limit(to.position() + limit); + nRead = fillReadBuffer(block, to); + to.flip(); + } else { + // Fill the read buffer as best we can. + nRead = fillReadBuffer(block); + + // Fill as much of the remaining byte array as possible with the + // data that was just read + if (nRead > 0) { + nRead = populateReadBuffer(to); + to.flip(); + } else if (nRead == 0 && !block) { + readInterest = true; + } + } + + return nRead; + } + } + + + @Override public void close() throws IOException { getSocket().close(); } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1758058&r1=1758057&r2=1758058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Sat Aug 27 16:46:27 2016 @@ -1162,6 +1162,44 @@ public class NioEndpoint extends Abstrac @Override + public int read(boolean block, ByteBuffer to) throws IOException { + int nRead = populateReadBuffer(to); + if (nRead > 0) { + to.flip(); + return nRead; + /* + * Since more bytes may have arrived since the buffer was last + * filled, it is an option at this point to perform a + * non-blocking read. However correctly handling the case if + * that read returns end of stream adds complexity. Therefore, + * at the moment, the preference is for simplicity. + */ + } + + // The socket read buffer capacity is socket.appReadBufSize + int limit = socketBufferHandler.getReadBuffer().capacity(); + if (to.remaining() >= limit) { + to.limit(to.position() + limit); + nRead = fillReadBuffer(block, to); + updateLastRead(); + to.flip(); + } else { + // Fill the read buffer as best we can. + nRead = fillReadBuffer(block); + updateLastRead(); + + // Fill as much of the remaining byte array as possible with the + // data that was just read + if (nRead > 0) { + nRead = populateReadBuffer(to); + to.flip(); + } + } + return nRead; + } + + + @Override public void close() throws IOException { getSocket().close(); } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java?rev=1758058&r1=1758057&r2=1758058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java Sat Aug 27 16:46:27 2016 @@ -278,6 +278,7 @@ public abstract class SocketWrapperBase< public abstract int read(boolean block, byte[] b, int off, int len) throws IOException; + public abstract int read(boolean block, ByteBuffer to) throws IOException; public abstract boolean isReadyForRead() throws IOException; protected int populateReadBuffer(byte[] b, int off, int len) { @@ -299,6 +300,19 @@ public abstract class SocketWrapperBase< } + protected int populateReadBuffer(ByteBuffer to) { + // Is there enough data in the read buffer to satisfy this request? + // Copy what data there is in the read buffer to the byte array + socketBufferHandler.configureReadBufferForRead(); + int nRead = transfer(socketBufferHandler.getReadBuffer(), to); + + if (log.isDebugEnabled()) { + log.debug("Socket: [" + this + "], Read from buffer: [" + nRead + "]"); + } + return nRead; + } + + /** * Return input that has been read to the input buffer for re-reading by the * correct component. There are times when a component may read more data @@ -1043,7 +1057,7 @@ public abstract class SocketWrapperBase< return max; } - protected static void transfer(ByteBuffer from, ByteBuffer to) { + protected static int transfer(ByteBuffer from, ByteBuffer to) { int max = Math.min(from.remaining(), to.remaining()); if (max > 0) { int fromLimit = from.limit(); @@ -1051,5 +1065,6 @@ public abstract class SocketWrapperBase< to.put(from); from.limit(fromLimit); } + return max; } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org