Author: markt Date: Thu May 17 20:46:57 2018 New Revision: 1831812 URL: http://svn.apache.org/viewvc?rev=1831812&view=rev Log: Fix some SpotBugs warnings While some warnings were false positives, some did point to some potential edge cases in the shutdown code. The code now explicitly checks that the thread has stopped rather than assuming it has.
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties tomcat/trunk/res/findbugs/filter-false-positives.xml tomcat/trunk/webapps/docs/changelog.xml 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=1831812&r1=1831811&r2=1831812&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Thu May 17 20:46:57 2018 @@ -682,20 +682,13 @@ public class AprEndpoint extends Abstrac // Start poller thread poller = new Poller(); poller.init(); - Thread pollerThread = new Thread(poller, getName() + "-Poller"); - pollerThread.setPriority(threadPriority); - pollerThread.setDaemon(true); - pollerThread.start(); + poller.start(); // Start sendfile thread if (getUseSendfile()) { sendfile = new Sendfile(); sendfile.init(); - Thread sendfileThread = - new Thread(sendfile, getName() + "-Sendfile"); - sendfileThread.setPriority(threadPriority); - sendfileThread.setDaemon(true); - sendfileThread.start(); + sendfile.start(); } startAcceptorThreads(); @@ -753,6 +746,7 @@ public class AprEndpoint extends Abstrac connections.clear(); if (getUseSendfile()) { try { + sendfile.stop(); sendfile.destroy(); } catch (Exception e) { // Ignore @@ -1278,7 +1272,7 @@ public class AprEndpoint extends Abstrac private AtomicInteger connectionCount = new AtomicInteger(0); public int getConnectionCount() { return connectionCount.get(); } - + private volatile Thread pollerThread; private volatile boolean pollerRunning = true; /** @@ -1348,12 +1342,22 @@ public class AprEndpoint extends Abstrac } + protected void start() { + pollerThread = new Thread(poller, getName() + "-Poller"); + pollerThread.setPriority(threadPriority); + pollerThread.setDaemon(true); + pollerThread.start(); + } + + /* * This method is synchronized so that it is not possible for a socket * to be added to the Poller's addList once this method has completed. */ protected synchronized void stop() { pollerRunning = false; + // In case the poller thread is in the idle wait + this.notify(); } @@ -1361,14 +1365,20 @@ public class AprEndpoint extends Abstrac * Destroy the poller. */ protected synchronized void destroy() { - // Wait for pollerTime before doing anything, so that the poller - // threads exit, otherwise parallel destruction of sockets which are - // still in the poller can cause problems - try { - this.notify(); - this.wait(pollerCount * pollTime / 1000); - } catch (InterruptedException e) { - // Ignore + // Wait for the poller thread to exit, otherwise parallel + // destruction of sockets which are still in the poller can cause + // problems. + int loops = pollerCount * 50; + while (loops > 0 && pollerThread.isAlive()) { + try { + this.wait(pollTime / 1000); + } catch (InterruptedException e) { + // Ignore + } + loops--; + } + if (pollerThread.isAlive()) { + log.warn(sm.getString("endpoint.pollerThreadStop")); } // Close all sockets in the close queue SocketInfo info = closeList.get(); @@ -1441,6 +1451,7 @@ public class AprEndpoint extends Abstrac // Add socket to the list. Newly added sockets will wait // at most for pollTime before being polled. if (addList.add(socket, timeout, flags)) { + // In case the poller thread is in the idle wait this.notify(); } } @@ -1474,6 +1485,7 @@ public class AprEndpoint extends Abstrac */ private synchronized void close(long socket) { closeList.add(socket, 0, 0); + // In case the poller thread is in the idle wait this.notify(); } @@ -1578,7 +1590,7 @@ public class AprEndpoint extends Abstrac // with no processing since the notify() call in // add()/close() would have no effect since it // happened before this sync block was entered - if (addList.size() < 1 && closeList.size() < 1) { + if (pollerRunning && addList.size() < 1 && closeList.size() < 1) { this.wait(10000); } } @@ -1921,6 +1933,7 @@ public class AprEndpoint extends Abstrac protected ArrayList<SendfileData> addS; + private volatile Thread sendfileThread; private volatile boolean sendfileRunning = true; /** @@ -1948,22 +1961,40 @@ public class AprEndpoint extends Abstrac addS = new ArrayList<>(); } - /** - * Destroy the poller. - */ - protected void destroy() { + protected void start() { + sendfileThread = new Thread(sendfile, getName() + "-Sendfile"); + sendfileThread.setPriority(threadPriority); + sendfileThread.setDaemon(true); + sendfileThread.start(); + } + + protected void stop() { sendfileRunning = false; - // Wait for polltime before doing anything, so that the poller threads - // exit, otherwise parallel destruction of sockets which are still - // in the poller can cause problems - try { - synchronized (this) { - this.notify(); + + // Wait for the sendfile thread to exit, otherwise parallel + // destruction of sockets which are still in the poller can cause + // problems. + int loops = 50; + while (loops > 0 && sendfileThread.isAlive()) { + try { this.wait(pollTime / 1000); + } catch (InterruptedException e) { + // Ignore } - } catch (InterruptedException e) { - // Ignore + loops--; } + if (sendfileThread.isAlive()) { + log.warn(sm.getString("endpoint.sendfileThreadStop")); + } + + // In case the sendfile thread is in the idle wait + this.notify(); + } + + /** + * Destroy the poller. + */ + protected void destroy() { // Close any socket remaining in the add queue for (int i = (addS.size() - 1); i >= 0; i--) { SendfileData data = addS.get(i); 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=1831812&r1=1831811&r2=1831812&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Thu May 17 20:46:57 2018 @@ -59,11 +59,13 @@ endpoint.poll.limitedpollsize=Failed to endpoint.poll.initfail=Poller creation failed endpoint.poll.fail=Critical poller failure (restarting poller): [{0}] [{1}] endpoint.poll.error=Unexpected poller error +endpoint.pollerThreadStop=The poller thread failed to stop in a timely manner endpoint.process.fail=Error allocating socket processor endpoint.processing.fail=Error running socket processor endpoint.removeDefaultSslHostConfig=The default SSLHostConfig (named [{0}]) may not be removed -endpoint.sendfile.error=Unexpected sendfile error endpoint.sendfile.addfail=Sendfile failure: [{0}] [{1}] +endpoint.sendfile.error=Unexpected sendfile error +endpoint.sendfileThreadStop=The sendfile thread failed to stop in a timely manner endpoint.setAttribute=Set [{0}] to [{1}] endpoint.timeout.err=Error processing socket timeout endpoint.unknownSslHostName=The SSL host name [{0}] is not recognised for this endpoint Modified: tomcat/trunk/res/findbugs/filter-false-positives.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/res/findbugs/filter-false-positives.xml?rev=1831812&r1=1831811&r2=1831812&view=diff ============================================================================== --- tomcat/trunk/res/findbugs/filter-false-positives.xml (original) +++ tomcat/trunk/res/findbugs/filter-false-positives.xml Thu May 17 20:46:57 2018 @@ -1092,6 +1092,11 @@ <Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD" /> </Match> <Match> + <!-- Field is populated by JNI code --> + <Class name="org.apache.tomcat.jni.Sockaddr" /> + <Bug pattern="UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD"/> + </Match> + <Match> <Class name="org.apache.tomcat.util.IntrospectionUtils" /> <Method name="findMethod"/> <Bug code="NP" /> @@ -1245,21 +1250,22 @@ <Bug code="MF" /> </Match> <Match> - <!-- JSSE vs APR attribute names. More confusing to change one of them --> - <Class name="org.apache.tomcat.util.net.AprEndpoint"/> - <Or> - <Method name="getSSLProtocol"/> - <Method name="setSSLProtocol"/> - </Or> - <Bug code="Nm"/> - </Match> - <Match> <!-- See wait() call in destroy() --> <Class name="org.apache.tomcat.util.net.AprEndpoint$Poller"/> <Method name="run"/> <Bug code="NN" /> </Match> <Match> + <!-- There is only a single wait in run() when the poller is idle --> + <Class name="org.apache.tomcat.util.net.AprEndpoint$Poller"/> + <Or> + <Method name="add"/> + <Method name="close"/> + <Method name="stop"/> + </Or> + <Bug pattern="NO_NOTIFY_NOT_NOTIFYALL" /> + </Match> + <Match> <Class name="org.apache.tomcat.util.net.AprEndpoint$Sendfile"/> <Method name="run"/> <Or> @@ -1270,6 +1276,15 @@ </Or> </Match> <Match> + <!-- There is only a single wait in run() when the poller is idle --> + <Class name="org.apache.tomcat.util.net.AprEndpoint$Sendfile"/> + <Or> + <Method name="add"/> + <Method name="stop"/> + </Or> + <Bug pattern="NO_NOTIFY_NOT_NOTIFYALL" /> + </Match> + <Match> <!-- Sync is there to protect referenced object not field --> <Class name="org.apache.tomcat.util.net.AprEndpoint$SocketEventProcessor"/> <Method name="run"/> Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1831812&r1=1831811&r2=1831812&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu May 17 20:46:57 2018 @@ -123,6 +123,10 @@ <fix> <bug>62371</bug>: Improve logging of Host validation failures. (markt) </fix> + <fix> + Fix a couple of unlikely edge cases in the shutting down of the + APR/native connector. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org