You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2019/04/15 22:13:18 UTC

[tomcat] branch master updated: Port NIO2 close refactoring to NIO

This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
     new 3d977d6  Port NIO2 close refactoring to NIO
3d977d6 is described below

commit 3d977d6138ae86725bbcb722036041a95425416a
Author: remm <re...@apache.org>
AuthorDate: Tue Apr 16 00:13:10 2019 +0200

    Port NIO2 close refactoring to NIO
    
    Fix socket close discrepancies for NIO, now the wrapper close is used
    everywhere except for socket accept problems.
---
 java/org/apache/tomcat/util/net/NioEndpoint.java | 76 +++++++++++++++---------
 webapps/docs/changelog.xml                       |  4 ++
 2 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java
index 7a9e708..b869876 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -531,8 +531,10 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel>
                         // processed. Count down the connections at this point
                         // since it won't have been counted down when the socket
                         // closed.
-                        socket.socketWrapper.getEndpoint().countDownConnection();
-                        ((NioSocketWrapper) socket.socketWrapper).closed = true;
+                        try {
+                            socket.socketWrapper.close();
+                        } catch (Exception ignore) {
+                        }
                     } else {
                         final NioSocketWrapper socketWrapper = (NioSocketWrapper) key.attachment();
                         if (socketWrapper != null) {
@@ -685,25 +687,18 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel>
                 }
                 socketWrapper = (NioSocketWrapper) sk.attach(null);
                 if (socketWrapper != null) {
-                    // If attachment is non-null then there may be a current
-                    // connection with an associated processor.
-                    getHandler().release(socketWrapper);
-                }
-                if (sk.isValid()) sk.cancel();
-                // If it is available, close the NioChannel first which should
-                // in turn close the underlying SocketChannel. The NioChannel
-                // needs to be closed first, if available, to ensure that TLS
-                // connections are shut down cleanly.
-                if (socketWrapper != null) {
                     try {
-                        socketWrapper.getSocket().close(true);
-                    } catch (Exception e){
+                        socketWrapper.close();
+                    } catch (Exception e) {
                         if (log.isDebugEnabled()) {
                             log.debug(sm.getString(
-                                    "endpoint.debug.socketCloseFail"), e);
+                                    "endpoint.debug.channelCloseFail"), e);
                         }
                     }
                 }
+                if (sk.isValid()) {
+                    sk.cancel();
+                }
                 // The SocketChannel is also available via the SelectionKey. If
                 // it hasn't been closed in the block above, close it now.
                 if (sk.channel().isOpen()) {
@@ -716,18 +711,6 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel>
                         }
                     }
                 }
-                try {
-                    if (socketWrapper != null && socketWrapper.getSendfileData() != null
-                            && socketWrapper.getSendfileData().fchannel != null
-                            && socketWrapper.getSendfileData().fchannel.isOpen()) {
-                        socketWrapper.getSendfileData().fchannel.close();
-                    }
-                } catch (Exception ignore) {
-                }
-                if (socketWrapper != null) {
-                    countDownConnection();
-                    socketWrapper.closed = true;
-                }
             } catch (Throwable e) {
                 ExceptionUtils.handleThrowable(e);
                 if (log.isDebugEnabled()) {
@@ -1215,7 +1198,44 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel>
 
         @Override
         public void close() throws IOException {
-            getSocket().close();
+            if (log.isDebugEnabled()) {
+                log.debug("Calling [" + getEndpoint() + "].closeSocket([" + this + "])", new Exception());
+            }
+            try {
+                getEndpoint().getHandler().release(this);
+            } catch (Throwable e) {
+                ExceptionUtils.handleThrowable(e);
+                if (log.isDebugEnabled()) {
+                    log.error("Channel close error", e);
+                }
+            }
+            try {
+                synchronized (getSocket()) {
+                    if (!closed) {
+                        closed = true;
+                        getEndpoint().countDownConnection();
+                    }
+                    if (getSocket().isOpen()) {
+                        getSocket().close(true);
+                    }
+                }
+            } catch (Throwable e) {
+                ExceptionUtils.handleThrowable(e);
+                if (log.isDebugEnabled()) {
+                    log.error("Channel close error", e);
+                }
+            }
+            try {
+                SendfileData data = getSendfileData();
+                if (data != null && data.fchannel != null && data.fchannel.isOpen()) {
+                    data.fchannel.close();
+                }
+            } catch (Throwable e) {
+                ExceptionUtils.handleThrowable(e);
+                if (log.isDebugEnabled()) {
+                    log.error("Channel close error", e);
+                }
+            }
         }
 
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ed16730..4def071 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -61,6 +61,10 @@
       <fix>
         Possible HTTP/2 connection leak issue when using async. (remm)
       </fix>
+      <fix>
+        Fix socket close discrepancies for NIO, now the wrapper close
+        is used everywhere except for socket accept problems. (remm)
+      </fix>
     </changelog>
   </subsection>
 </section>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org