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:47:30 UTC
svn commit: r1637937 - in /tomcat/trunk/java/org/apache:
coyote/http11/upgrade/AprServletOutputStream.java
tomcat/util/net/AprEndpoint.java
Author: markt
Date: Mon Nov 10 16:47:30 2014
New Revision: 1637937
URL: http://svn.apache.org/r1637937
Log:
Push write methods down to SocketWrapper for APR
Modified:
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java?rev=1637937&r1=1637936&r2=1637937&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java Mon Nov 10 16:47:30 2014
@@ -16,143 +16,27 @@
*/
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.tomcat.jni.OS;
-import org.apache.tomcat.jni.Socket;
-import org.apache.tomcat.jni.Status;
-import org.apache.tomcat.util.net.AprEndpoint;
+
+import org.apache.tomcat.util.net.AprEndpoint.AprSocketWrapper;
import org.apache.tomcat.util.net.SocketWrapperBase;
public class AprServletOutputStream extends AbstractServletOutputStream<Long> {
- private static final int SSL_OUTPUT_BUFFER_SIZE = 8192;
-
- private final long socket;
- private volatile boolean closed = false;
- private final ByteBuffer sslOutputBuffer;
-
public AprServletOutputStream(SocketWrapperBase<Long> socketWrapper,
int asyncWriteBufferSize) {
super(socketWrapper, asyncWriteBufferSize);
- this.socket = socketWrapper.getSocket().longValue();
- if (socketWrapper.getEndpoint().isSSLEnabled()) {
- sslOutputBuffer = ByteBuffer.allocateDirect(SSL_OUTPUT_BUFFER_SIZE);
- sslOutputBuffer.position(SSL_OUTPUT_BUFFER_SIZE);
- } else {
- sslOutputBuffer = null;
- }
}
@Override
- protected int doWrite(boolean block, byte[] b, int off, int len)
- throws IOException {
-
- if (closed) {
- throw new IOException(sm.getString("apr.closed", Long.valueOf(socket)));
- }
-
- Lock readLock = socketWrapper.getBlockingStatusReadLock();
- WriteLock writeLock = socketWrapper.getBlockingStatusWriteLock();
-
- readLock.lock();
- try {
- if (socketWrapper.getBlockingStatus() == block) {
- return doWriteInternal(b, off, len);
- }
- } finally {
- readLock.unlock();
- }
-
- writeLock.lock();
- try {
- // Set the current settings for this socket
- socketWrapper.setBlockingStatus(block);
- if (block) {
- Socket.timeoutSet(socket, socketWrapper.getEndpoint().getSoTimeout() * 1000);
- } else {
- Socket.timeoutSet(socket, 0);
- }
-
- // Downgrade the lock
- readLock.lock();
- try {
- writeLock.unlock();
- return doWriteInternal(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();
- }
- }
- }
-
-
- private int doWriteInternal(byte[] b, int off, int len) throws IOException {
-
- int start = off;
- int left = len;
- int written;
-
- do {
- if (socketWrapper.getEndpoint().isSSLEnabled()) {
- if (sslOutputBuffer.remaining() == 0) {
- // Buffer was fully written last time around
- sslOutputBuffer.clear();
- if (left < SSL_OUTPUT_BUFFER_SIZE) {
- sslOutputBuffer.put(b, start, left);
- } else {
- sslOutputBuffer.put(b, start, SSL_OUTPUT_BUFFER_SIZE);
- }
- sslOutputBuffer.flip();
- } else {
- // Buffer still has data from previous attempt to write
- // APR + SSL requires that exactly the same parameters are
- // passed when re-attempting the write
- }
- written = Socket.sendb(socket, sslOutputBuffer,
- sslOutputBuffer.position(), sslOutputBuffer.limit());
- if (written > 0) {
- sslOutputBuffer.position(
- sslOutputBuffer.position() + written);
- }
- } else {
- written = Socket.send(socket, b, start, left);
- }
- if (Status.APR_STATUS_IS_EAGAIN(-written)) {
- written = 0;
- } else if (-written == Status.APR_EOF) {
- throw new EOFException(sm.getString("apr.clientAbort"));
- } else if ((OS.IS_WIN32 || OS.IS_WIN64) &&
- (-written == Status.APR_OS_START_SYSERR + 10053)) {
- // 10053 on Windows is connection aborted
- throw new EOFException(sm.getString("apr.clientAbort"));
- } else if (written < 0) {
- throw new IOException(sm.getString("apr.write.error",
- Integer.valueOf(-written), Long.valueOf(socket), socketWrapper));
- }
- start += written;
- left -= written;
- } while (written > 0 && left > 0);
-
- if (left > 0) {
- ((AprEndpoint) socketWrapper.getEndpoint()).getPoller().add(socket, -1, false, true);
- }
- return len - left;
+ protected int doWrite(boolean block, byte[] b, int off, int len) throws IOException {
+ return ((AprSocketWrapper) socketWrapper).write(block, b, off, len);
}
@Override
protected void doFlush() throws IOException {
- // TODO Auto-generated method stub
+ ((AprSocketWrapper) socketWrapper).flush();
}
}
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=1637937&r1=1637936&r2=1637937&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:47:30 2014
@@ -2353,7 +2353,11 @@ public class AprEndpoint extends Abstrac
public static class AprSocketWrapper extends SocketWrapperBase<Long> {
- private ByteBuffer leftOverInput;
+ private static final int SSL_OUTPUT_BUFFER_SIZE = 8192;
+
+ private final ByteBuffer sslOutputBuffer;
+
+ private volatile ByteBuffer leftOverInput;
private volatile boolean eagain = false;
private volatile boolean closed = false;
@@ -2363,6 +2367,13 @@ public class AprEndpoint extends Abstrac
public AprSocketWrapper(Long socket, AprEndpoint endpoint) {
super(socket, endpoint);
+
+ if (endpoint.isSSLEnabled()) {
+ sslOutputBuffer = ByteBuffer.allocateDirect(SSL_OUTPUT_BUFFER_SIZE);
+ sslOutputBuffer.position(SSL_OUTPUT_BUFFER_SIZE);
+ } else {
+ sslOutputBuffer = null;
+ }
}
@@ -2470,5 +2481,110 @@ public class AprEndpoint extends Abstrac
// AbstractProcessor needs to trigger the close as multiple closes for
// APR/native sockets will cause problems.
}
+
+
+ public int write(boolean block, byte[] b, int off, int len) throws IOException {
+
+ if (closed) {
+ throw new IOException(sm.getString("apr.closed", getSocket()));
+ }
+
+ Lock readLock = getBlockingStatusReadLock();
+ WriteLock writeLock = getBlockingStatusWriteLock();
+
+ readLock.lock();
+ try {
+ if (getBlockingStatus() == block) {
+ return doWriteInternal(b, off, len);
+ }
+ } finally {
+ readLock.unlock();
+ }
+
+ writeLock.lock();
+ try {
+ // Set the current settings for this socket
+ setBlockingStatus(block);
+ if (block) {
+ Socket.timeoutSet(getSocket().longValue(), getEndpoint().getSoTimeout() * 1000);
+ } else {
+ Socket.timeoutSet(getSocket().longValue(), 0);
+ }
+
+ // Downgrade the lock
+ readLock.lock();
+ try {
+ writeLock.unlock();
+ return doWriteInternal(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();
+ }
+ }
+ }
+
+
+ private int doWriteInternal(byte[] b, int off, int len) throws IOException {
+
+ int start = off;
+ int left = len;
+ int written;
+
+ do {
+ if (getEndpoint().isSSLEnabled()) {
+ if (sslOutputBuffer.remaining() == 0) {
+ // Buffer was fully written last time around
+ sslOutputBuffer.clear();
+ if (left < SSL_OUTPUT_BUFFER_SIZE) {
+ sslOutputBuffer.put(b, start, left);
+ } else {
+ sslOutputBuffer.put(b, start, SSL_OUTPUT_BUFFER_SIZE);
+ }
+ sslOutputBuffer.flip();
+ } else {
+ // Buffer still has data from previous attempt to write
+ // APR + SSL requires that exactly the same parameters are
+ // passed when re-attempting the write
+ }
+ written = Socket.sendb(getSocket().longValue(), sslOutputBuffer,
+ sslOutputBuffer.position(), sslOutputBuffer.limit());
+ if (written > 0) {
+ sslOutputBuffer.position(
+ sslOutputBuffer.position() + written);
+ }
+ } else {
+ written = Socket.send(getSocket().longValue(), b, start, left);
+ }
+ if (Status.APR_STATUS_IS_EAGAIN(-written)) {
+ written = 0;
+ } else if (-written == Status.APR_EOF) {
+ throw new EOFException(sm.getString("apr.clientAbort"));
+ } else if ((OS.IS_WIN32 || OS.IS_WIN64) &&
+ (-written == Status.APR_OS_START_SYSERR + 10053)) {
+ // 10053 on Windows is connection aborted
+ throw new EOFException(sm.getString("apr.clientAbort"));
+ } else if (written < 0) {
+ throw new IOException(sm.getString("apr.write.error",
+ Integer.valueOf(-written), getSocket(), this));
+ }
+ start += written;
+ left -= written;
+ } while (written > 0 && left > 0);
+
+ if (left > 0) {
+ ((AprEndpoint) getEndpoint()).getPoller().add(getSocket().longValue(), -1, false, true);
+ }
+ return len - left;
+ }
+
+
+ public void flush() {
+ // NO-OP
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org