Author: markt
Date: Thu Mar 23 12:42:54 2017
New Revision: 1788232

URL: http://svn.apache.org/viewvc?rev=1788232&view=rev
Log:
Speed up shutdown when using multiple acceptor threads by ensuring that the 
code that unlocks the acceptor threads correctly handles the case where there 
are multiple threads.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings_es.properties
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1788232&r1=1788231&r2=1788232&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Thu Mar 
23 12:42:54 2017
@@ -760,14 +760,13 @@ public abstract class AbstractEndpoint<S
      */
     protected void unlockAccept() {
         // Only try to unlock the acceptor if it is necessary
-        boolean unlockRequired = false;
+        int unlocksRequired = 0;
         for (Acceptor<U> acceptor : acceptors) {
             if (acceptor.getState() == AcceptorState.RUNNING) {
-                unlockRequired = true;
-                break;
+                unlocksRequired++;
             }
         }
-        if (!unlockRequired) {
+        if (unlocksRequired == 0) {
             return;
         }
 
@@ -776,61 +775,60 @@ public abstract class AbstractEndpoint<S
         try {
             localAddress = getLocalAddress();
         } catch (IOException ioe) {
-            // TODO i18n
-            getLog().debug("Unable to determine local address for " + 
getName(), ioe);
+            getLog().debug(sm.getString("endpoint.debug.unlock.localFail", 
getName()), ioe);
         }
         if (localAddress == null) {
-            // TODO i18n
-            getLog().warn("Failed to unlock acceptor for " + getName() + " 
because the local address was not available.");
+            getLog().warn(sm.getString("endpoint.debug.unlock.localNone", 
getName()));
             return;
         }
 
         try {
             unlockAddress = getUnlockAddress(localAddress);
 
-            try (java.net.Socket s = new java.net.Socket()) {
-                int stmo = 2 * 1000;
-                int utmo = 2 * 1000;
-                if (getSocketProperties().getSoTimeout() > stmo)
-                    stmo = getSocketProperties().getSoTimeout();
-                if (getSocketProperties().getUnlockTimeout() > utmo)
-                    utmo = getSocketProperties().getUnlockTimeout();
-                s.setSoTimeout(stmo);
-                
s.setSoLinger(getSocketProperties().getSoLingerOn(),getSocketProperties().getSoLingerTime());
-                if (getLog().isDebugEnabled()) {
-                    getLog().debug("About to unlock socket for:" + 
unlockAddress);
-                }
-                s.connect(unlockAddress,utmo);
-                if (getDeferAccept()) {
-                    /*
-                     * In the case of a deferred accept / accept filters we 
need to
-                     * send data to wake up the accept. Send OPTIONS * to 
bypass
-                     * even BSD accept filters. The Acceptor will discard it.
-                     */
-                    OutputStreamWriter sw;
-
-                    sw = new OutputStreamWriter(s.getOutputStream(), 
"ISO-8859-1");
-                    sw.write("OPTIONS * HTTP/1.0\r\n" +
-                             "User-Agent: Tomcat wakeup connection\r\n\r\n");
-                    sw.flush();
-                }
-                if (getLog().isDebugEnabled()) {
-                    getLog().debug("Socket unlock completed for:" + 
unlockAddress);
-                }
+            for (int i = 0; i < unlocksRequired; i++) {
+                try (java.net.Socket s = new java.net.Socket()) {
+                    int stmo = 2 * 1000;
+                    int utmo = 2 * 1000;
+                    if (getSocketProperties().getSoTimeout() > stmo)
+                        stmo = getSocketProperties().getSoTimeout();
+                    if (getSocketProperties().getUnlockTimeout() > utmo)
+                        utmo = getSocketProperties().getUnlockTimeout();
+                    s.setSoTimeout(stmo);
+                    
s.setSoLinger(getSocketProperties().getSoLingerOn(),getSocketProperties().getSoLingerTime());
+                    if (getLog().isDebugEnabled()) {
+                        getLog().debug("About to unlock socket for:" + 
unlockAddress);
+                    }
+                    s.connect(unlockAddress,utmo);
+                    if (getDeferAccept()) {
+                        /*
+                         * In the case of a deferred accept / accept filters 
we need to
+                         * send data to wake up the accept. Send OPTIONS * to 
bypass
+                         * even BSD accept filters. The Acceptor will discard 
it.
+                         */
+                        OutputStreamWriter sw;
 
-                // Wait for upto 1000ms acceptor threads to unlock
-                long waitLeft = 1000;
-                for (Acceptor<U> acceptor : acceptors) {
-                    while (waitLeft > 0 &&
-                            acceptor.getState() == AcceptorState.RUNNING) {
-                        Thread.sleep(50);
-                        waitLeft -= 50;
+                        sw = new OutputStreamWriter(s.getOutputStream(), 
"ISO-8859-1");
+                        sw.write("OPTIONS * HTTP/1.0\r\n" +
+                                 "User-Agent: Tomcat wakeup 
connection\r\n\r\n");
+                        sw.flush();
+                    }
+                    if (getLog().isDebugEnabled()) {
+                        getLog().debug("Socket unlock completed for:" + 
unlockAddress);
                     }
                 }
             }
+            // Wait for upto 1000ms acceptor threads to unlock
+            long waitLeft = 1000;
+            for (Acceptor<U> acceptor : acceptors) {
+                while (waitLeft > 0 &&
+                        acceptor.getState() == AcceptorState.RUNNING) {
+                    Thread.sleep(50);
+                    waitLeft -= 50;
+                }
+            }
         } catch(Exception e) {
             if (getLog().isDebugEnabled()) {
-                getLog().debug(sm.getString("endpoint.debug.unlock", "" + 
getPort()), e);
+                getLog().debug(sm.getString("endpoint.debug.unlock.fail", "" + 
getPort()), e);
             }
         }
     }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1788232&r1=1788231&r2=1788232&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Thu 
Mar 23 12:42:54 2017
@@ -37,7 +37,9 @@ endpoint.debug.pollerRemoved=Removed [{0
 endpoint.debug.socket=socket [{0}]
 endpoint.debug.socketCloseFail=Failed to close socket
 endpoint.debug.socketTimeout=Timing out [{0}]
-endpoint.debug.unlock=Caught exception trying to unlock accept on port {0}
+endpoint.debug.unlock.fail=Caught exception trying to unlock accept on port 
[{0}]
+endpoint.debug.unlock.localFail=Unable to determine local address for [{0}]
+endpoint.debug.unlock.localNone=Failed to unlock acceptor for [{0}] because 
the local address was not available
 endpoint.accept.fail=Socket accept failed
 endpoint.alpn.fail=Failed to configure endpoint for ALPN using {0}
 endpoint.alpn.negotiated=Negotiated [{0}] protocol using ALPN

Modified: 
tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings_es.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings_es.properties?rev=1788232&r1=1788231&r2=1788232&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings_es.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings_es.properties Thu 
Mar 23 12:42:54 2017
@@ -15,7 +15,7 @@
 # net resources
 endpoint.err.handshake = Acuerdo fallido
 endpoint.err.unexpected = Error inesperado al procesar conector
-endpoint.debug.unlock = Excepci\u00F3n cogida intentando desbloquear 
aceptaci\u00F3n en puerto {0}
+endpoint.debug.unlock.fail = Excepci\u00F3n cogida intentando desbloquear 
aceptaci\u00F3n en puerto {0}
 endpoint.err.close = Excepci\u00F3n cogida intentando cerrar conector
 endpoint.init.bind = Ligado de conector fall\u00F3\: [{0}] {1}
 endpoint.init.listen = Escucha de conector fall\u00F3\: [{0}] {1}

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1788232&r1=1788231&r2=1788232&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Mar 23 12:42:54 2017
@@ -113,6 +113,11 @@
         Poller if a connection is closed at the same time as new data arrives 
on
         that connection. (markt)
       </fix>
+      <fix>
+        Speed up shutdown when using multiple acceptor threads by ensuring that
+        the code that unlocks the acceptor threads correctly handles the case
+        where there are multiple threads. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="jdbc-pool">



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

Reply via email to