Index: java/org/apache/catalina/core/StandardService.java =================================================================== --- java/org/apache/catalina/core/StandardService.java (revision 1835198) +++ java/org/apache/catalina/core/StandardService.java (working copy) @@ -458,6 +458,9 @@ synchronized (connectorsLock) { for (Connector connector: connectors) { connector.pause(); + // Close server socket if bindOnInit is false + // Note: bindOnInit test is in AbstractEndpoint + connector.getProtocolHandler().closeServerSocket(); } } Index: java/org/apache/coyote/AbstractProtocol.java =================================================================== --- java/org/apache/coyote/AbstractProtocol.java (revision 1835198) +++ java/org/apache/coyote/AbstractProtocol.java (working copy) @@ -631,6 +631,12 @@ } + @Override + public void closeServerSocket() { + endpoint.closeServerSocket(); + } + + // ------------------------------------------- Connection handler base class protected static class ConnectionHandler implements AbstractEndpoint.Handler { Index: java/org/apache/coyote/ProtocolHandler.java =================================================================== --- java/org/apache/coyote/ProtocolHandler.java (revision 1835198) +++ java/org/apache/coyote/ProtocolHandler.java (working copy) @@ -101,6 +101,13 @@ /** + * Close the server socket (to prevent further connections) if bindOnInit is + * {@code false} but do not perform any further shutdown. + */ + public void closeServerSocket(); + + + /** * Requires APR/native library * * @return true if this Protocol Handler requires the Index: java/org/apache/tomcat/util/net/AbstractEndpoint.java =================================================================== --- java/org/apache/tomcat/util/net/AbstractEndpoint.java (revision 1835198) +++ java/org/apache/tomcat/util/net/AbstractEndpoint.java (working copy) @@ -1206,6 +1206,29 @@ } else return -1; } + + /** + * Close the server socket (to prevent further connections) if + * {@link #getBindOnInit()} is {@code false}. + */ + public final void closeServerSocket() { + if (!getBindOnInit()) { + try { + doCloseServerSocket(); + } catch (IOException ioe) { + getLog().warn(sm.getString("endpoint.serverSocket.closeFailed", getName()), ioe); + } + } + } + + + /** + * Actually close the server socket but don't perform any other clean-up. + * + * @throws IOException If an error occurs closing the socket + */ + protected abstract void doCloseServerSocket() throws IOException; + protected abstract U serverSocketAccept() throws Exception; protected abstract boolean setSocketOptions(U socket); Index: java/org/apache/tomcat/util/net/AprEndpoint.java =================================================================== --- java/org/apache/tomcat/util/net/AprEndpoint.java (revision 1835198) +++ java/org/apache/tomcat/util/net/AprEndpoint.java (working copy) @@ -92,7 +92,7 @@ /** * Server socket "pointer". */ - protected long serverSock = 0; + protected volatile long serverSock = 0; /** @@ -774,11 +774,7 @@ serverSockPool = 0; } - // Close server socket if it was initialised - if (serverSock != 0) { - Socket.close(serverSock); - serverSock = 0; - } + doCloseServerSocket(); if (sslContext != 0) { Long ctx = Long.valueOf(sslContext); @@ -799,6 +795,16 @@ } + @Override + protected void doCloseServerSocket() { + // Close server socket if it was initialised + if (serverSock != 0) { + Socket.close(serverSock); + serverSock = 0; + } + } + + // ------------------------------------------------------ Protected Methods /** Index: java/org/apache/tomcat/util/net/LocalStrings.properties =================================================================== --- java/org/apache/tomcat/util/net/LocalStrings.properties (revision 1835198) +++ java/org/apache/tomcat/util/net/LocalStrings.properties (working copy) @@ -67,6 +67,7 @@ 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.serverSocket.closeFailed=Failed to close server socket for [{0}] 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 Index: java/org/apache/tomcat/util/net/Nio2Endpoint.java =================================================================== --- java/org/apache/tomcat/util/net/Nio2Endpoint.java (revision 1835198) +++ java/org/apache/tomcat/util/net/Nio2Endpoint.java (working copy) @@ -70,7 +70,7 @@ /** * Server socket "pointer". */ - private AsynchronousServerSocketChannel serverSock = null; + private volatile AsynchronousServerSocketChannel serverSock = null; /** * Allows detecting if a completion handler completes inline. @@ -227,9 +227,7 @@ if (running) { stop(); } - // Close server socket - serverSock.close(); - serverSock = null; + doCloseServerSocket(); destroySsl(); super.unbind(); // Unlike other connectors, the thread pool is tied to the server socket @@ -241,6 +239,16 @@ @Override + protected void doCloseServerSocket() throws IOException { + // Close server socket + if (serverSock != null) { + serverSock.close(); + serverSock = null; + } + } + + + @Override public void shutdownExecutor() { if (threadGroup != null && internalExecutor) { try { Index: java/org/apache/tomcat/util/net/NioEndpoint.java =================================================================== --- java/org/apache/tomcat/util/net/NioEndpoint.java (revision 1835198) +++ java/org/apache/tomcat/util/net/NioEndpoint.java (working copy) @@ -85,7 +85,7 @@ /** * Server socket "pointer". */ - private ServerSocketChannel serverSock = null; + private volatile ServerSocketChannel serverSock = null; /** * @@ -328,12 +328,7 @@ if (running) { stop(); } - if (!getUseInheritedChannel()) { - // Close server socket - serverSock.socket().close(); - serverSock.close(); - } - serverSock = null; + doCloseServerSocket(); destroySsl(); super.unbind(); if (getHandler() != null ) { @@ -346,6 +341,17 @@ } + @Override + protected void doCloseServerSocket() throws IOException { + if (!getUseInheritedChannel() && serverSock != null) { + // Close server socket + serverSock.socket().close(); + serverSock.close(); + serverSock = null; + } + } + + // ------------------------------------------------------ Protected Methods public NioSelectorPool getSelectorPool() {