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 2014/11/10 17:46:10 UTC
svn commit: r1637925 - in /tomcat/trunk/java/org/apache:
coyote/http11/upgrade/AprProcessor.java
coyote/http11/upgrade/AprServletInputStream.java
tomcat/util/net/AprEndpoint.java
Author: markt
Date: Mon Nov 10 16:46:09 2014
New Revision: 1637925
URL: http://svn.apache.org/r1637925
Log:
Push down read methods to AprSocketWrapper
Modified:
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java?rev=1637925&r1=1637924&r2=1637925&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java Mon Nov 10 16:46:09 2014
@@ -24,6 +24,7 @@ import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.jni.Socket;
import org.apache.tomcat.util.net.AprEndpoint;
+import org.apache.tomcat.util.net.AprEndpoint.AprSocketWrapper;
import org.apache.tomcat.util.net.SocketWrapperBase;
public class AprProcessor extends AbstractProcessor<Long> {
@@ -34,13 +35,13 @@ public class AprProcessor extends Abstra
private static final int INFINITE_TIMEOUT = -1;
- public AprProcessor(SocketWrapperBase<Long> wrapper, ByteBuffer leftoverInput,
+ public AprProcessor(SocketWrapperBase<Long> wrapper, ByteBuffer leftOverInput,
HttpUpgradeHandler httpUpgradeProcessor, AprEndpoint endpoint,
int asyncWriteBufferSize) {
super(httpUpgradeProcessor,
- new AprServletInputStream(wrapper, leftoverInput),
+ new AprServletInputStream(wrapper),
new AprServletOutputStream(wrapper, asyncWriteBufferSize, endpoint));
-
+ ((AprSocketWrapper) wrapper).setLeftOverInput(leftOverInput);
Socket.timeoutSet(wrapper.getSocket().longValue(), INFINITE_TIMEOUT);
}
}
Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java?rev=1637925&r1=1637924&r2=1637925&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java Mon Nov 10 16:46:09 2014
@@ -16,136 +16,31 @@
*/
package org.apache.coyote.http11.upgrade;
-import java.io.EOFException;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
-
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.jni.OS;
-import org.apache.tomcat.jni.Socket;
-import org.apache.tomcat.jni.Status;
+
+import org.apache.tomcat.util.net.AprEndpoint.AprSocketWrapper;
import org.apache.tomcat.util.net.SocketWrapperBase;
public class AprServletInputStream extends AbstractServletInputStream {
- private static final Log log = LogFactory.getLog(AprServletInputStream.class);
-
private final SocketWrapperBase<Long> wrapper;
- private final long socket;
- private ByteBuffer leftoverInput;
- private volatile boolean eagain = false;
- private volatile boolean closed = false;
-
- public AprServletInputStream(SocketWrapperBase<Long> wrapper, ByteBuffer leftoverInput) {
+ public AprServletInputStream(SocketWrapperBase<Long> wrapper) {
this.wrapper = wrapper;
- this.socket = wrapper.getSocket().longValue();
- if (leftoverInput != null) {
- this.leftoverInput = ByteBuffer.allocate(leftoverInput.remaining());
- this.leftoverInput.put(leftoverInput);
- }
}
-
@Override
- protected int doRead(boolean block, byte[] b, int off, int len)
- throws IOException {
-
- if (closed) {
- throw new IOException(sm.getString("apr.closed", Long.valueOf(socket)));
- }
-
- if (leftoverInput != null) {
- if (leftoverInput.remaining() < len) {
- len = leftoverInput.remaining();
- }
- leftoverInput.get(b, off, len);
- if (leftoverInput.remaining() == 0) {
- leftoverInput = null;
- }
- return len;
- }
-
- Lock readLock = wrapper.getBlockingStatusReadLock();
- WriteLock writeLock = wrapper.getBlockingStatusWriteLock();
-
- boolean readDone = false;
- int result = 0;
- readLock.lock();
- try {
- if (wrapper.getBlockingStatus() == block) {
- result = Socket.recv(socket, b, off, len);
- readDone = true;
- }
- } finally {
- readLock.unlock();
- }
-
- if (!readDone) {
- writeLock.lock();
- try {
- wrapper.setBlockingStatus(block);
- // Set the current settings for this socket
- Socket.optSet(socket, Socket.APR_SO_NONBLOCK, (block ? 0 : 1));
- // Downgrade the lock
- readLock.lock();
- try {
- writeLock.unlock();
- result = Socket.recv(socket, b, off, len);
- } finally {
- readLock.unlock();
- }
- } finally {
- // Should have been released above but may not have been on some
- // exception paths
- if (writeLock.isHeldByCurrentThread()) {
- writeLock.unlock();
- }
- }
- }
-
- if (result > 0) {
- eagain = false;
- return result;
- } else if (-result == Status.EAGAIN) {
- eagain = true;
- return 0;
- } else if (-result == Status.APR_EGENERAL && wrapper.isSecure()) {
- // Not entirely sure why this is necessary. Testing to date has not
- // identified any issues with this but log it so it can be tracked
- // if it is suspected of causing issues in the future.
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("apr.read.sslGeneralError",
- Long.valueOf(socket), wrapper));
- }
- eagain = true;
- return 0;
- } else if (-result == Status.APR_EOF) {
- throw new EOFException(sm.getString("apr.clientAbort"));
- } else if ((OS.IS_WIN32 || OS.IS_WIN64) &&
- (-result == Status.APR_OS_START_SYSERR + 10053)) {
- // 10053 on Windows is connection aborted
- throw new EOFException(sm.getString("apr.clientAbort"));
- } else {
- throw new IOException(sm.getString("apr.read.error",
- Integer.valueOf(-result), Long.valueOf(socket), wrapper));
- }
+ protected boolean doIsReady() throws IOException {
+ return ((AprSocketWrapper) wrapper).doIsReady();
}
-
@Override
- protected boolean doIsReady() {
- return !eagain;
+ protected int doRead(boolean block, byte[] b, int off, int len) throws IOException {
+ return ((AprSocketWrapper) wrapper).doRead(block, b, off, len);
}
-
@Override
protected void doClose() throws IOException {
- closed = true;
- // AbstractProcessor needs to trigger the close as multiple closes for
- // APR/native sockets will cause problems.
+ ((AprSocketWrapper) wrapper).doClose();
}
}
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=1637925&r1=1637924&r2=1637925&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Mon Nov 10 16:46:09 2014
@@ -16,6 +16,9 @@
*/
package org.apache.tomcat.util.net;
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -23,6 +26,8 @@ import java.util.concurrent.ConcurrentHa
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -2346,13 +2351,122 @@ public class AprEndpoint extends Abstrac
}
- private static class AprSocketWrapper extends SocketWrapperBase<Long> {
+ public static class AprSocketWrapper extends SocketWrapperBase<Long> {
+
+ private ByteBuffer leftOverInput;
+ private volatile boolean eagain = false;
+ private volatile boolean closed = false;
// This field should only be used by Poller#run()
private int pollerFlags = 0;
+
public AprSocketWrapper(Long socket, AprEndpoint endpoint) {
super(socket, endpoint);
}
+
+
+ public void setLeftOverInput(ByteBuffer leftOverInput) {
+ if (leftOverInput != null) {
+ this.leftOverInput = ByteBuffer.allocate(leftOverInput.remaining());
+ this.leftOverInput.put(leftOverInput);
+ }
+ }
+
+
+ public int doRead(boolean block, byte[] b, int off, int len)
+ throws IOException {
+
+ if (closed) {
+ throw new IOException(sm.getString("apr.closed", getSocket()));
+ }
+
+ if (leftOverInput != null) {
+ if (leftOverInput.remaining() < len) {
+ len = leftOverInput.remaining();
+ }
+ leftOverInput.get(b, off, len);
+ if (leftOverInput.remaining() == 0) {
+ leftOverInput = null;
+ }
+ return len;
+ }
+
+ Lock readLock = getBlockingStatusReadLock();
+ WriteLock writeLock = getBlockingStatusWriteLock();
+
+ boolean readDone = false;
+ int result = 0;
+ readLock.lock();
+ try {
+ if (getBlockingStatus() == block) {
+ result = Socket.recv(getSocket().longValue(), b, off, len);
+ readDone = true;
+ }
+ } finally {
+ readLock.unlock();
+ }
+
+ if (!readDone) {
+ writeLock.lock();
+ try {
+ setBlockingStatus(block);
+ // Set the current settings for this socket
+ Socket.optSet(getSocket().longValue(), Socket.APR_SO_NONBLOCK, (block ? 0 : 1));
+ // Downgrade the lock
+ readLock.lock();
+ try {
+ writeLock.unlock();
+ result = Socket.recv(getSocket().longValue(), b, off, len);
+ } finally {
+ readLock.unlock();
+ }
+ } finally {
+ // Should have been released above but may not have been on some
+ // exception paths
+ if (writeLock.isHeldByCurrentThread()) {
+ writeLock.unlock();
+ }
+ }
+ }
+
+ if (result > 0) {
+ eagain = false;
+ 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
+ // identified any issues with this but log it so it can be tracked
+ // if it is suspected of causing issues in the future.
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("apr.read.sslGeneralError", getSocket(), this));
+ }
+ eagain = true;
+ return 0;
+ } else if (-result == Status.APR_EOF) {
+ throw new EOFException(sm.getString("apr.clientAbort"));
+ } else if ((OS.IS_WIN32 || OS.IS_WIN64) &&
+ (-result == Status.APR_OS_START_SYSERR + 10053)) {
+ // 10053 on Windows is connection aborted
+ throw new EOFException(sm.getString("apr.clientAbort"));
+ } else {
+ throw new IOException(sm.getString("apr.read.error",
+ Integer.valueOf(-result), getSocket(), this));
+ }
+ }
+
+
+ public boolean doIsReady() {
+ return !eagain;
+ }
+
+
+ public void doClose() {
+ closed = true;
+ // AbstractProcessor needs to trigger the close as multiple closes for
+ // APR/native sockets will cause problems.
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org