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