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