You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/02/27 16:01:39 UTC
svn commit: r1662710 -
/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Author: markt
Date: Fri Feb 27 15:01:39 2015
New Revision: 1662710
URL: http://svn.apache.org/r1662710
Log:
Align APR with NIO & NIO2.
Fixes all unit test faiures except tests that use SSL
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.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=1662710&r1=1662709&r2=1662710&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri Feb 27 15:01:39 2015
@@ -2357,8 +2357,6 @@ public class AprEndpoint extends Abstrac
private final ByteBuffer sslOutputBuffer;
- private volatile ByteBuffer returnedInput;
- private volatile boolean eagain = false;
private volatile boolean closed = false;
// This field should only be used by Poller#run()
@@ -2388,7 +2386,53 @@ public class AprEndpoint extends Abstrac
@Override
- public int read(boolean block, byte[] b, int off, int len) throws IOException {
+ public int read(boolean block, byte[] b, int off, int len)
+ throws IOException {
+
+ socketBufferHandler.configureReadBufferForRead();
+ ByteBuffer readBuffer = socketBufferHandler.getReadBuffer();
+ int remaining = readBuffer.remaining();
+
+ // Is there enough data in the read buffer to satisfy this request?
+ if (remaining >= len) {
+ readBuffer.get(b, off, len);
+ return len;
+ }
+
+ // Copy what data there is in the read buffer to the byte array
+ if (remaining > 0) {
+ readBuffer.get(b, off, remaining);
+ return remaining;
+ /*
+ * 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.
+ */
+ }
+
+ // Fill the read buffer as best we can.
+ int nRead = fillReadBuffer(block);
+
+ // Full as much of the remaining byte array as possible with the
+ // data that was just read
+ if (nRead > 0) {
+ socketBufferHandler.configureReadBufferForRead();
+ if (nRead > len) {
+ readBuffer.get(b, off, len);
+ return len;
+ } else {
+ readBuffer.get(b, off, nRead);
+ return nRead;
+ }
+ } else {
+ return nRead;
+ }
+ }
+
+
+ private int fillReadBuffer(boolean block) throws IOException {
// TODO: Restore a socket level input buffer to align with NIO and
// NIO2.
@@ -2396,16 +2440,8 @@ public class AprEndpoint extends Abstrac
throw new IOException(sm.getString("socket.apr.closed", getSocket()));
}
- if (returnedInput != null) {
- if (returnedInput.remaining() < len) {
- len = returnedInput.remaining();
- }
- returnedInput.get(b, off, len);
- if (returnedInput.remaining() == 0) {
- returnedInput = null;
- }
- return len;
- }
+ socketBufferHandler.configureReadBufferForWrite();
+ ByteBuffer socketReadBuffer = socketBufferHandler.getReadBuffer();
Lock readLock = getBlockingStatusReadLock();
WriteLock writeLock = getBlockingStatusWriteLock();
@@ -2418,7 +2454,8 @@ public class AprEndpoint extends Abstrac
if (block) {
Socket.timeoutSet(getSocket().longValue(), getReadTimeout() * 1000);
}
- result = Socket.recv(getSocket().longValue(), b, off, len);
+ result = Socket.recvb(getSocket().longValue(),
+ socketReadBuffer, socketReadBuffer.position(), socketReadBuffer.remaining());
readDone = true;
}
} finally {
@@ -2439,7 +2476,8 @@ public class AprEndpoint extends Abstrac
readLock.lock();
try {
writeLock.unlock();
- result = Socket.recv(getSocket().longValue(), b, off, len);
+ result = Socket.recvb(getSocket().longValue(),
+ socketReadBuffer, socketReadBuffer.position(), socketReadBuffer.remaining());
} finally {
readLock.unlock();
}
@@ -2453,10 +2491,9 @@ public class AprEndpoint extends Abstrac
}
if (result > 0) {
- eagain = false;
+ socketReadBuffer.position(socketReadBuffer.position() + result);
return result;
} else if (-result == Status.EAGAIN) {
- eagain = true;
return 0;
} else if (-result == Status.APR_EGENERAL && isSecure()) {
// Not entirely sure why this is necessary. Testing to date has not
@@ -2465,7 +2502,6 @@ public class AprEndpoint extends Abstrac
if (log.isDebugEnabled()) {
log.debug(sm.getString("socket.apr.read.sslGeneralError", getSocket(), this));
}
- eagain = true;
return 0;
} else if ((-result) == Status.ETIMEDOUT || (-result) == Status.TIMEUP) {
if (block) {
@@ -2494,17 +2530,26 @@ public class AprEndpoint extends Abstrac
@Override
- public boolean isReadyForRead() {
- return !eagain;
+ public boolean isReadyForRead() throws IOException {
+ socketBufferHandler.configureReadBufferForRead();
+
+ if (socketBufferHandler.getReadBuffer().remaining() > 0) {
+ return true;
+ }
+
+ fillReadBuffer(false);
+
+ boolean isReady = socketBufferHandler.getReadBuffer().position() > 0;
+ return isReady;
}
@Override
- public void unRead(ByteBuffer input) {
+ public void unRead(ByteBuffer returnedInput) {
if (returnedInput != null) {
- this.returnedInput = ByteBuffer.allocate(returnedInput.remaining());
- this.returnedInput.put(returnedInput);
+ socketBufferHandler.configureReadBufferForWrite();
+ socketBufferHandler.getReadBuffer().put(returnedInput);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org