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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org