Make sure ChannelHandler.handlerRemoved() is invoked while handler methods are not running
- Fixes #1664
This commit is contained in:
parent
3049f5ddc4
commit
3b1881b523
@ -34,6 +34,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
private final DefaultChannelPipeline pipeline;
|
private final DefaultChannelPipeline pipeline;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final ChannelHandler handler;
|
private final ChannelHandler handler;
|
||||||
|
private int callDepth;
|
||||||
private boolean removed;
|
private boolean removed;
|
||||||
|
|
||||||
// Will be set to null if no child executor should be used, otherwise it will be set to the
|
// Will be set to null if no child executor should be used, otherwise it will be set to the
|
||||||
@ -77,6 +78,10 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isRunning() {
|
||||||
|
return callDepth != 0;
|
||||||
|
}
|
||||||
|
|
||||||
void freeInbound() {
|
void freeInbound() {
|
||||||
EventExecutor executor = executor();
|
EventExecutor executor = executor();
|
||||||
if (executor.inEventLoop()) {
|
if (executor.inEventLoop()) {
|
||||||
@ -186,7 +191,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeChannelRegistered() {
|
private void invokeChannelRegistered() {
|
||||||
try {
|
try {
|
||||||
((ChannelInboundHandler) handler()).channelRegistered(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelRegistered(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -211,7 +221,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeChannelUnregistered() {
|
private void invokeChannelUnregistered() {
|
||||||
try {
|
try {
|
||||||
((ChannelInboundHandler) handler()).channelUnregistered(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelUnregistered(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -236,7 +251,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeChannelActive() {
|
private void invokeChannelActive() {
|
||||||
try {
|
try {
|
||||||
((ChannelInboundHandler) handler()).channelActive(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelActive(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -261,7 +281,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeChannelInactive() {
|
private void invokeChannelInactive() {
|
||||||
try {
|
try {
|
||||||
((ChannelInboundHandler) handler()).channelInactive(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelInactive(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -298,9 +323,13 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void invokeExceptionCaught(final Throwable cause) {
|
private void invokeExceptionCaught(final Throwable cause) {
|
||||||
ChannelHandler handler = handler();
|
try {
|
||||||
|
callDepth ++;
|
||||||
try {
|
try {
|
||||||
handler.exceptionCaught(this, cause);
|
handler.exceptionCaught(this, cause);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
@ -332,9 +361,13 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void invokeUserEventTriggered(Object event) {
|
private void invokeUserEventTriggered(Object event) {
|
||||||
ChannelInboundHandler handler = (ChannelInboundHandler) handler();
|
|
||||||
try {
|
try {
|
||||||
handler.userEventTriggered(this, event);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).userEventTriggered(this, event);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -362,9 +395,13 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void invokeChannelRead(Object msg) {
|
private void invokeChannelRead(Object msg) {
|
||||||
ChannelInboundHandler handler = (ChannelInboundHandler) handler();
|
|
||||||
try {
|
try {
|
||||||
handler.channelRead(this, msg);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelRead(this, msg);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -393,7 +430,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeChannelReadComplete() {
|
private void invokeChannelReadComplete() {
|
||||||
try {
|
try {
|
||||||
((ChannelInboundHandler) handler()).channelReadComplete(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelReadComplete(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -422,7 +464,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeChannelWritabilityChanged() {
|
private void invokeChannelWritabilityChanged() {
|
||||||
try {
|
try {
|
||||||
((ChannelInboundHandler) handler()).channelWritabilityChanged(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelInboundHandler) handler).channelWritabilityChanged(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -483,7 +530,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeBind(SocketAddress localAddress, ChannelPromise promise) {
|
private void invokeBind(SocketAddress localAddress, ChannelPromise promise) {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).bind(this, localAddress, promise);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).bind(this, localAddress, promise);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyOutboundHandlerException(t, promise);
|
notifyOutboundHandlerException(t, promise);
|
||||||
}
|
}
|
||||||
@ -521,7 +573,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeConnect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
|
private void invokeConnect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).connect(this, remoteAddress, localAddress, promise);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).connect(this, remoteAddress, localAddress, promise);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyOutboundHandlerException(t, promise);
|
notifyOutboundHandlerException(t, promise);
|
||||||
}
|
}
|
||||||
@ -556,7 +613,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeDisconnect(ChannelPromise promise) {
|
private void invokeDisconnect(ChannelPromise promise) {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).disconnect(this, promise);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).disconnect(this, promise);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyOutboundHandlerException(t, promise);
|
notifyOutboundHandlerException(t, promise);
|
||||||
}
|
}
|
||||||
@ -584,7 +646,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeClose(ChannelPromise promise) {
|
private void invokeClose(ChannelPromise promise) {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).close(this, promise);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).close(this, promise);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyOutboundHandlerException(t, promise);
|
notifyOutboundHandlerException(t, promise);
|
||||||
}
|
}
|
||||||
@ -612,7 +679,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeDeregister(ChannelPromise promise) {
|
private void invokeDeregister(ChannelPromise promise) {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).deregister(this, promise);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).deregister(this, promise);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyOutboundHandlerException(t, promise);
|
notifyOutboundHandlerException(t, promise);
|
||||||
}
|
}
|
||||||
@ -642,7 +714,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeRead() {
|
private void invokeRead() {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).read(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).read(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -677,9 +754,13 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void invokeWrite(Object msg, ChannelPromise promise) {
|
private void invokeWrite(Object msg, ChannelPromise promise) {
|
||||||
ChannelOutboundHandler handler = (ChannelOutboundHandler) handler();
|
|
||||||
try {
|
try {
|
||||||
handler.write(this, msg, promise);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).write(this, msg, promise);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyOutboundHandlerException(t, promise);
|
notifyOutboundHandlerException(t, promise);
|
||||||
}
|
}
|
||||||
@ -709,7 +790,12 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
|
|
||||||
private void invokeFlush() {
|
private void invokeFlush() {
|
||||||
try {
|
try {
|
||||||
((ChannelOutboundHandler) handler()).flush(this);
|
callDepth ++;
|
||||||
|
try {
|
||||||
|
((ChannelOutboundHandler) handler).flush(this);
|
||||||
|
} finally {
|
||||||
|
callDepth --;
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
notifyHandlerException(t);
|
notifyHandlerException(t);
|
||||||
}
|
}
|
||||||
@ -831,7 +917,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
DefaultChannelHandlerContext ctx = this;
|
DefaultChannelHandlerContext ctx = this;
|
||||||
do {
|
do {
|
||||||
ctx = ctx.next;
|
ctx = ctx.next;
|
||||||
} while (!(ctx.handler() instanceof ChannelInboundHandler));
|
} while (!(ctx.handler instanceof ChannelInboundHandler));
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,7 +925,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
DefaultChannelHandlerContext ctx = this;
|
DefaultChannelHandlerContext ctx = this;
|
||||||
do {
|
do {
|
||||||
ctx = ctx.prev;
|
ctx = ctx.prev;
|
||||||
} while (!(ctx.handler() instanceof ChannelOutboundHandler));
|
} while (!(ctx.handler instanceof ChannelOutboundHandler));
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +506,8 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void callHandlerRemoved(final DefaultChannelHandlerContext ctx) {
|
private void callHandlerRemoved(final DefaultChannelHandlerContext ctx) {
|
||||||
if (ctx.channel().isRegistered() && !ctx.executor().inEventLoop()) {
|
if (ctx.channel().isRegistered()) {
|
||||||
|
if (!ctx.executor().inEventLoop() || ctx.isRunning()) {
|
||||||
ctx.executor().execute(new Runnable() {
|
ctx.executor().execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -515,6 +516,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
callHandlerRemoved0(ctx);
|
callHandlerRemoved0(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user