NETTY-417 client channel still open after close and wait
* Fixed a race condition where NioSocketChannel's state variable is updated *after* its close future is notified * Removed unnecessary use of ChannelFutureListeners in NioSocketChannel and AbstractChannel
This commit is contained in:
parent
e85996ea46
commit
c6fa82729c
@ -32,7 +32,6 @@ import org.jboss.netty.util.internal.ConcurrentHashMap;
|
|||||||
public abstract class AbstractChannel implements Channel {
|
public abstract class AbstractChannel implements Channel {
|
||||||
|
|
||||||
static final ConcurrentMap<Integer, Channel> allChannels = new ConcurrentHashMap<Integer, Channel>();
|
static final ConcurrentMap<Integer, Channel> allChannels = new ConcurrentHashMap<Integer, Channel>();
|
||||||
private static final IdDeallocator ID_DEALLOCATOR = new IdDeallocator();
|
|
||||||
|
|
||||||
private static Integer allocateId(Channel channel) {
|
private static Integer allocateId(Channel channel) {
|
||||||
Integer id = Integer.valueOf(System.identityHashCode(channel));
|
Integer id = Integer.valueOf(System.identityHashCode(channel));
|
||||||
@ -49,17 +48,6 @@ public abstract class AbstractChannel implements Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class IdDeallocator implements ChannelFutureListener {
|
|
||||||
IdDeallocator() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
|
||||||
allChannels.remove(future.getChannel().getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Integer id;
|
private final Integer id;
|
||||||
private final Channel parent;
|
private final Channel parent;
|
||||||
private final ChannelFactory factory;
|
private final ChannelFactory factory;
|
||||||
@ -94,7 +82,6 @@ public abstract class AbstractChannel implements Channel {
|
|||||||
this.pipeline = pipeline;
|
this.pipeline = pipeline;
|
||||||
|
|
||||||
id = allocateId(this);
|
id = allocateId(this);
|
||||||
closeFuture.addListener(ID_DEALLOCATOR);
|
|
||||||
|
|
||||||
pipeline.attach(this, sink);
|
pipeline.attach(this, sink);
|
||||||
}
|
}
|
||||||
@ -200,6 +187,10 @@ public abstract class AbstractChannel implements Channel {
|
|||||||
* closed yet
|
* closed yet
|
||||||
*/
|
*/
|
||||||
protected boolean setClosed() {
|
protected boolean setClosed() {
|
||||||
|
// Deallocate the current channel's ID from allChannels so that other
|
||||||
|
// new channels can use it.
|
||||||
|
allChannels.remove(id);
|
||||||
|
|
||||||
return closeFuture.setClosed();
|
return closeFuture.setClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,15 +83,6 @@ class NioSocketChannel extends AbstractChannel
|
|||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.worker = worker;
|
this.worker = worker;
|
||||||
config = new DefaultNioSocketChannelConfig(socket.socket());
|
config = new DefaultNioSocketChannelConfig(socket.socket());
|
||||||
|
|
||||||
// TODO Move the state variable to AbstractChannel so that we don't need
|
|
||||||
// to add many listeners.
|
|
||||||
getCloseFuture().addListener(new ChannelFutureListener() {
|
|
||||||
@Override
|
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
|
||||||
state = ST_CLOSED;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -157,6 +148,7 @@ class NioSocketChannel extends AbstractChannel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean setClosed() {
|
protected boolean setClosed() {
|
||||||
|
state = ST_CLOSED;
|
||||||
return super.setClosed();
|
return super.setClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user