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 what to do. The default is to not remove the Channel
from the ChannelLocal to not break usage which depends on the "old"
behavior. See NETTY-447
This commit is contained in:
norman 2011-10-24 08:32:17 +02:00
parent 322f0ccae4
commit 6728766158

View File

@ -40,13 +40,31 @@ public class ChannelLocal<T> {
private final ConcurrentMap<Channel, T> map =
new ConcurrentIdentityWeakKeyHashMap<Channel, T>();
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 <code>false</code> as parameter
*/
public ChannelLocal() {
super();
this(false);
}
/**
* Creates a {@link Channel} local variable.
*
* @param removeOnClose if <code>true</code> 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
* {@code null}. Override it to change the initial value.
@ -88,7 +106,11 @@ public class ChannelLocal<T> {
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 +127,12 @@ public class ChannelLocal<T> {
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 +153,9 @@ public class ChannelLocal<T> {
if (removed == null) {
return initialValue(channel);
} else {
if (removeOnClose) {
channel.getCloseFuture().removeListener(remover);
}
return removed;
}
}