diff --git a/resolver/src/main/java/io/netty/resolver/AddressResolverGroup.java b/resolver/src/main/java/io/netty/resolver/AddressResolverGroup.java index 19bde8c687..7020219293 100644 --- a/resolver/src/main/java/io/netty/resolver/AddressResolverGroup.java +++ b/resolver/src/main/java/io/netty/resolver/AddressResolverGroup.java @@ -19,7 +19,9 @@ package io.netty.resolver; import static java.util.Objects.requireNonNull; import io.netty.util.concurrent.EventExecutor; +import io.netty.util.concurrent.Future; import io.netty.util.concurrent.FutureListener; +import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -41,13 +43,16 @@ public abstract class AddressResolverGroup implements C */ private final Map> resolvers = new IdentityHashMap<>(); + private final Map>> executorTerminationListeners = + new IdentityHashMap<>(); + protected AddressResolverGroup() { } /** * Returns the {@link AddressResolver} associated with the specified {@link EventExecutor}. If there's no associated - * resolved found, this method creates and returns a new resolver instance created by + * resolver found, this method creates and returns a new resolver instance created by * {@link #newResolver(EventExecutor)} so that the new resolver is reused on another - * {@link #getResolver(EventExecutor)} call with the same {@link EventExecutor}. + * {@code #getResolver(EventExecutor)} call with the same {@link EventExecutor}. */ public AddressResolver getResolver(final EventExecutor executor) { requireNonNull(executor, "executor"); @@ -68,12 +73,15 @@ public abstract class AddressResolverGroup implements C } resolvers.put(executor, newResolver); - executor.terminationFuture().addListener((FutureListener) future -> { + FutureListener terminationListener = future -> { synchronized (resolvers) { resolvers.remove(executor); + executorTerminationListeners.remove(executor); } newResolver.close(); - }); + }; + executorTerminationListeners.put(executor, terminationListener); + executor.terminationFuture().addListener(terminationListener); r = newResolver; } @@ -97,9 +105,17 @@ public abstract class AddressResolverGroup implements C synchronized (resolvers) { rArray = (AddressResolver[]) resolvers.values().toArray(new AddressResolver[0]); resolvers.clear(); + + for (final Map.Entry>> entry : + executorTerminationListeners.entrySet()) { + + entry.getKey().terminationFuture().removeListener(entry.getValue()); + } + + executorTerminationListeners.clear(); } - for (AddressResolver r: rArray) { + for (final AddressResolver r: rArray) { try { r.close(); } catch (Throwable t) {