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