Source:
<code>public void stop(final boolean criticalError) throws Exception { if (!started) { return; } failureCheckAndFlushThread.close(criticalError); for (Acceptor acceptor : acceptors.values()) { if (logger.isDebugEnabled()) { logger.debug("Pausing acceptor " + acceptor); } try { acceptor.pause(); } catch (Throwable t) { ActiveMQServerLogger.LOGGER.errorStoppingAcceptor(acceptor.getName()); } } if (logger.isDebugEnabled()) { logger.debug("Sending disconnect on live connections"); } HashSet<ConnectionEntry> connectionEntries = new HashSet<>(connections.values()); for (ConnectionEntry entry : connectionEntries) { RemotingConnection conn = entry.connection; if (logger.isTraceEnabled()) { logger.trace("Sending connection.disconnection packet to " + conn); } conn.disconnect(criticalError); } Map<Acceptor, Future<?>> acceptorFutures = new HashMap<>(); for (Acceptor acceptor : acceptors.values()) { try { acceptorFutures.put(acceptor, acceptor.asyncStop()); } catch (Throwable t) { ActiveMQServerLogger.LOGGER.errorStoppingAcceptor(acceptor.getName()); } } long acceptorTimeout = System.currentTimeMillis() + 3000; for (Map.Entry<Acceptor, Future<?>> acceptorFuture : acceptorFutures.entrySet()) { if (acceptorFuture.getValue() != null) { try { <START> acceptorFuture.getValue().get(Math.max(0, acceptorTimeout - System.currentTimeMillis()), TimeUnit.MILLISECONDS); <END> } catch (Throwable t) { ActiveMQServerLogger.LOGGER.errorStoppingAcceptor(acceptorFuture.getKey().getName()); } } } acceptors.clear(); acceptorFutures.clear(); connections.clear(); connectionCountLatch.setCount(0); if (managementService != null) { managementService.unregisterAcceptors(); } threadPool.shutdown(); if (!criticalError) { boolean ok = threadPool.awaitTermination(10000, TimeUnit.MILLISECONDS); if (!ok) { ActiveMQServerLogger.LOGGER.timeoutRemotingThreadPool(); } } started = false; }</code><technical_language>acceptors dont close in time? port bindings left hanging (and a network fd)? Is a chance this leave in worse state. is blocking close acceptor affecting fd leak making async helping, this is clear me. Surely fd acceptor running..... This needs a unit test recreating problem. Please dont merge a unit test</technical_language>

Target:
public void stop(final boolean criticalError) throws Exception { if (!started) { return; } failureCheckAndFlushThread.close(criticalError); for (Acceptor acceptor : acceptors.values()) { if (logger.isDebugEnabled()) { logger.debug("Pausing acceptor " + acceptor); } try { acceptor.pause(); } catch (Throwable t) { ActiveMQServerLogger.LOGGER.errorStoppingAcceptor(acceptor.getName()); } } if (logger.isDebugEnabled()) { logger.debug("Sending disconnect on live connections"); } HashSet<ConnectionEntry> connectionEntries = new HashSet<>(connections.values()); for (ConnectionEntry entry : connectionEntries) { RemotingConnection conn = entry.connection; if (logger.isTraceEnabled()) { logger.trace("Sending connection.disconnection packet to " + conn); } conn.disconnect(criticalError); } CountDownLatch acceptorCountDownLatch = new CountDownLatch(acceptors.size()); for (Acceptor acceptor : acceptors.values()) { try { acceptor.asyncStop(() -> acceptorCountDownLatch.countDown()); } catch (Throwable t) { ActiveMQServerLogger.LOGGER.errorStoppingAcceptor(acceptor.getName()); } } acceptorCountDownLatch.await(ACCEPTOR_STOP_TIMEOUT, TimeUnit.MILLISECONDS); acceptors.clear(); connections.clear(); connectionCountLatch.setCount(0); if (managementService != null) { managementService.unregisterAcceptors(); } threadPool.shutdown(); if (!criticalError) { boolean ok = threadPool.awaitTermination(10000, TimeUnit.MILLISECONDS); if (!ok) { ActiveMQServerLogger.LOGGER.timeoutRemotingThreadPool(); } } started = false; }