Index: java/org/apache/catalina/core/LocalStrings.properties =================================================================== --- java/org/apache/catalina/core/LocalStrings.properties (revision 1835176) +++ java/org/apache/catalina/core/LocalStrings.properties (working copy) @@ -203,6 +203,7 @@ standardService.engine.stopFailed=Failed to stop associated Engine standardService.mapperListener.startFailed=Failed to start associated MapperListener standardService.mapperListener.stopFailed=Failed to stop associated MapperListener +standardService.serverSocket.closeFailed=Failed to close server socket for [{0}] standardService.start.name=Starting service [{0}] standardService.stop.name=Stopping service [{0}] standardWrapper.allocate=Error allocating a servlet instance Index: java/org/apache/catalina/core/StandardService.java =================================================================== --- java/org/apache/catalina/core/StandardService.java (revision 1835176) +++ java/org/apache/catalina/core/StandardService.java (working copy) @@ -19,6 +19,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.IOException; import java.util.ArrayList; import javax.management.ObjectName; @@ -458,6 +459,15 @@ synchronized (connectorsLock) { for (Connector connector: connectors) { connector.pause(); + if (!Boolean.parseBoolean((String) connector.getProperty("bindOnInit"))) { + // Close server socket + try { + connector.getProtocolHandler().closeServerSocket(); + } catch (IOException e) { + log.warn(sm.getString( + "standardService.serverSocket.closeFailed", connector), e); + } + } } } Index: java/org/apache/coyote/AbstractProtocol.java =================================================================== --- java/org/apache/coyote/AbstractProtocol.java (revision 1835176) +++ java/org/apache/coyote/AbstractProtocol.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.coyote; +import java.io.IOException; import java.net.InetAddress; import java.nio.ByteBuffer; import java.util.Collections; @@ -631,6 +632,12 @@ } + @Override + public void closeServerSocket() throws IOException { + 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 1835176) +++ java/org/apache/coyote/ProtocolHandler.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.coyote; +import java.io.IOException; import java.util.concurrent.Executor; import org.apache.tomcat.util.net.SSLHostConfig; @@ -101,6 +102,15 @@ /** + * Close the server socket (to prevent further connections) but do not + * perform any further shutdown. + * + * @throws IOException If an error occurs closing the server socket + */ + public void closeServerSocket() throws IOException; + + + /** * 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 1835176) +++ java/org/apache/tomcat/util/net/AbstractEndpoint.java (working copy) @@ -64,6 +64,8 @@ protected static final StringManager sm = StringManager.getManager(AbstractEndpoint.class); + private static final String SOCKET_PROPERTY_PREFIX = "socket."; + public static interface Handler { /** @@ -741,10 +743,10 @@ public boolean setProperty(String name, String value) { setAttribute(name, value); - final String socketName = "socket."; try { - if (name.startsWith(socketName)) { - return IntrospectionUtils.setProperty(socketProperties, name.substring(socketName.length()), value); + if (name.startsWith(SOCKET_PROPERTY_PREFIX)) { + return IntrospectionUtils.setProperty( + socketProperties, name.substring(SOCKET_PROPERTY_PREFIX.length()), value); } else { return IntrospectionUtils.setProperty(this,name,value,false); } @@ -755,9 +757,14 @@ } public String getProperty(String name) { String value = (String) getAttribute(name); - final String socketName = "socket."; - if (value == null && name.startsWith(socketName)) { - Object result = IntrospectionUtils.getProperty(socketProperties, name.substring(socketName.length())); + if (value == null) { + Object result; + if (name.startsWith(SOCKET_PROPERTY_PREFIX)) { + result = IntrospectionUtils.getProperty( + socketProperties, name.substring(SOCKET_PROPERTY_PREFIX.length())); + } else { + result = IntrospectionUtils.getProperty(this, name); + } if (result != null) { value = result.toString(); } @@ -1208,6 +1215,8 @@ protected abstract U serverSocketAccept() throws Exception; + public abstract void closeServerSocket() throws IOException; + protected abstract boolean setSocketOptions(U socket); protected abstract void closeSocket(U socket); Index: java/org/apache/tomcat/util/net/AprEndpoint.java =================================================================== --- java/org/apache/tomcat/util/net/AprEndpoint.java (revision 1835176) +++ 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; - } + closeServerSocket(); if (sslContext != 0) { Long ctx = Long.valueOf(sslContext); @@ -799,6 +795,16 @@ } + @Override + public void closeServerSocket() { + // Close server socket if it was initialised + if (serverSock != 0) { + Socket.close(serverSock); + serverSock = 0; + } + } + + // ------------------------------------------------------ Protected Methods /** Index: java/org/apache/tomcat/util/net/Nio2Endpoint.java =================================================================== --- java/org/apache/tomcat/util/net/Nio2Endpoint.java (revision 1835176) +++ 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; + closeServerSocket(); destroySsl(); super.unbind(); // Unlike other connectors, the thread pool is tied to the server socket @@ -241,6 +239,16 @@ @Override + public void closeServerSocket() 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 1835176) +++ 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; + closeServerSocket(); destroySsl(); super.unbind(); if (getHandler() != null ) { @@ -346,6 +341,17 @@ } + @Override + public void closeServerSocket() throws IOException { + if (!getUseInheritedChannel() && serverSock != null) { + // Close server socket + serverSock.socket().close(); + serverSock.close(); + serverSock = null; + } + } + + // ------------------------------------------------------ Protected Methods public NioSelectorPool getSelectorPool() {