From 6dce4098d71247a226a8a763ddc06e6ac0af08e8 Mon Sep 17 00:00:00 2001 From: norman Date: Mon, 24 Oct 2011 08:25:59 +0200 Subject: [PATCH] ChannelLocal nows removes Channel instances from itself once the Channel was closed. This is configurable via a constructor parameter to allow the user to choose the old behavior. The default is the new one. See NETTY-447 --- .../org/jboss/netty/channel/ChannelLocal.java | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jboss/netty/channel/ChannelLocal.java b/src/main/java/org/jboss/netty/channel/ChannelLocal.java index 4328003e55..522fb82976 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelLocal.java +++ b/src/main/java/org/jboss/netty/channel/ChannelLocal.java @@ -40,12 +40,32 @@ public class ChannelLocal { private final ConcurrentMap map = new ConcurrentIdentityWeakKeyHashMap(); + private final ChannelFutureListener remover = new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + remove(future.getChannel()); + } + }; + + private final boolean removeOnClose; + /** - * Creates a {@link Channel} local variable. + * Creates a {@link Channel} local variable by calling {@link #ChannelLocal(boolean)} with true */ public ChannelLocal() { - super(); + this(true); } + + /** + * Creates a {@link Channel} local variable. + * + * @param removeOnClose if true the {@link ChannelLocal} will remove a {@link Channel} from it own once the {@link Channel} was closed. + */ + public ChannelLocal(boolean removeOnClose) { + this.removeOnClose = removeOnClose; + } + + /** * Returns the initial value of the variable. By default, it returns @@ -88,7 +108,11 @@ public class ChannelLocal { if (channel == null) { throw new NullPointerException("channel"); } - return map.put(channel, value); + T old = map.put(channel, value); + if (removeOnClose) { + channel.getCloseFuture().addListener(remover); + } + return old; } } @@ -105,7 +129,12 @@ public class ChannelLocal { if (channel == null) { throw new NullPointerException("channel"); } - return map.putIfAbsent(channel, value); + T mapping = map.putIfAbsent(channel, value); + + if (removeOnClose && mapping == null) { + channel.getCloseFuture().addListener(remover); + } + return mapping; } } @@ -126,6 +155,9 @@ public class ChannelLocal { if (removed == null) { return initialValue(channel); } else { + if (removeOnClose) { + channel.getCloseFuture().removeListener(remover); + } return removed; } }