This is an automated email from the ASF dual-hosted git repository. amichair pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/aries-rsa.git
commit 41b1bbdc96d4bf06b65f12fdabd545f8e53e61e7 Author: Amichai Rothman <[email protected]> AuthorDate: Thu May 21 09:12:44 2026 +0300 ARIES-2228 Fix FastBinProvider socket not closed on shutdown --- .../rsa/provider/fastbin/FastBinProvider.java | 7 +++- .../provider/fastbin/tcp/TcpTransportServer.java | 39 ++++++++++++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/FastBinProvider.java b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/FastBinProvider.java index 2962b684..16388e60 100644 --- a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/FastBinProvider.java +++ b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/FastBinProvider.java @@ -45,6 +45,7 @@ import org.apache.aries.rsa.spi.IntentUnsatisfiedException; import org.apache.aries.rsa.util.StringPlus; import org.fusesource.hawtdispatch.Dispatch; import org.fusesource.hawtdispatch.DispatchQueue; +import org.fusesource.hawtdispatch.ShutdownException; import org.osgi.framework.BundleContext; import org.osgi.service.remoteserviceadmin.EndpointDescription; import org.osgi.service.remoteserviceadmin.RemoteConstants; @@ -90,7 +91,11 @@ public class FastBinProvider implements DistributionProvider { } public void close() { - client.stop(); + try { + client.stop(); + } catch (ShutdownException se) { + LOG.trace("exception while shutting down client", se); + } final Semaphore counter = new Semaphore(0); server.stop(() -> counter.release(1)); try { diff --git a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/tcp/TcpTransportServer.java b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/tcp/TcpTransportServer.java index 729b53d7..6fa593a4 100644 --- a/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/tcp/TcpTransportServer.java +++ b/provider/fastbin/src/main/java/org/apache/aries/rsa/provider/fastbin/tcp/TcpTransportServer.java @@ -30,6 +30,8 @@ import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import org.apache.aries.rsa.provider.fastbin.io.TransportAcceptListener; import org.apache.aries.rsa.provider.fastbin.io.TransportServer; @@ -163,22 +165,39 @@ public class TcpTransportServer implements TransportServer { public void stop() { stop(null); } + public void stop(final Runnable onCompleted) { if (acceptSource.isCanceled()) { onCompleted.run(); } else { - acceptSource.setCancelHandler(new Runnable() { - public void run() { - try { - channel.close(); - } catch (IOException e) { - } - if (onCompleted != null) { - onCompleted.run(); - } - } + CountDownLatch latch = new CountDownLatch(1); + acceptSource.setCancelHandler(() -> { + closeChannel(onCompleted); + latch.countDown(); }); acceptSource.cancel(); + // due to a race condition, sometimes during shutdown the hawt dispatcher + // bundle is stopped before we get here, so the handler above will never + // get executed. We give it a chance, but make sure to ultimately close + // the channel anyway to avoid leaving the socket in use. + try { + latch.await(5, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + if (channel.isOpen()) { // always close at the end + closeChannel(onCompleted); + } + } + } + + private void closeChannel(Runnable onCompleted) { + try { + channel.close(); + } catch (IOException ioe) { + } + if (onCompleted != null) { + onCompleted.run(); } }
