Revert "[#1442] Make sure closing the channel will not cause an UnsupportedOperationException"
This reverts commit a1a86b9de4
because the
semantic of ctx.isRemoved() is confusing to a user - why is
ctx.isRemoved() false when handlerRemoved() is invoked? A better
solution would be check if the connection is inactive and mark the
promise as failure before attempting to write anything.
This commit is contained in:
parent
30bfb989c1
commit
25c51279cf
@ -125,7 +125,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
DefaultChannelHandlerContext prev = this.prev;
|
DefaultChannelHandlerContext prev = this.prev;
|
||||||
if (prev != null) {
|
if (prev != null) {
|
||||||
synchronized (pipeline) {
|
synchronized (pipeline) {
|
||||||
pipeline.remove0(this, true);
|
pipeline.remove0(this);
|
||||||
}
|
}
|
||||||
prev.teardown();
|
prev.teardown();
|
||||||
}
|
}
|
||||||
|
@ -316,14 +316,14 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (!ctx.channel().isRegistered() || ctx.executor().inEventLoop()) {
|
if (!ctx.channel().isRegistered() || ctx.executor().inEventLoop()) {
|
||||||
remove0(ctx, false);
|
remove0(ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
} else {
|
} else {
|
||||||
future = ctx.executor().submit(new Runnable() {
|
future = ctx.executor().submit(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (DefaultChannelPipeline.this) {
|
synchronized (DefaultChannelPipeline.this) {
|
||||||
remove0(ctx, false);
|
remove0(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -339,13 +339,13 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove0(DefaultChannelHandlerContext ctx, boolean tearDown) {
|
void remove0(DefaultChannelHandlerContext ctx) {
|
||||||
DefaultChannelHandlerContext prev = ctx.prev;
|
DefaultChannelHandlerContext prev = ctx.prev;
|
||||||
DefaultChannelHandlerContext next = ctx.next;
|
DefaultChannelHandlerContext next = ctx.next;
|
||||||
prev.next = next;
|
prev.next = next;
|
||||||
next.prev = prev;
|
next.prev = prev;
|
||||||
name2ctx.remove(ctx.name());
|
name2ctx.remove(ctx.name());
|
||||||
callHandlerRemoved(ctx, tearDown);
|
callHandlerRemoved(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -450,7 +450,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
// because callHandlerRemoved() will trigger inboundBufferUpdated() or flush() on newHandler and those
|
// because callHandlerRemoved() will trigger inboundBufferUpdated() or flush() on newHandler and those
|
||||||
// event handlers must be called after handlerAdded().
|
// event handlers must be called after handlerAdded().
|
||||||
callHandlerAdded(newCtx);
|
callHandlerAdded(newCtx);
|
||||||
callHandlerRemoved(oldCtx, false);
|
callHandlerRemoved(oldCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkMultiplicity(ChannelHandlerContext ctx) {
|
private static void checkMultiplicity(ChannelHandlerContext ctx) {
|
||||||
@ -505,26 +505,24 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void callHandlerRemoved(final DefaultChannelHandlerContext ctx, final boolean tearDown) {
|
private void callHandlerRemoved(final DefaultChannelHandlerContext ctx) {
|
||||||
if (ctx.channel().isRegistered() && !ctx.executor().inEventLoop()) {
|
if (ctx.channel().isRegistered() && !ctx.executor().inEventLoop()) {
|
||||||
ctx.executor().execute(new Runnable() {
|
ctx.executor().execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
callHandlerRemoved0(ctx, tearDown);
|
callHandlerRemoved0(ctx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callHandlerRemoved0(ctx, tearDown);
|
callHandlerRemoved0(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void callHandlerRemoved0(final DefaultChannelHandlerContext ctx, boolean tearDown) {
|
private void callHandlerRemoved0(final DefaultChannelHandlerContext ctx) {
|
||||||
// Notify the complete removal.
|
// Notify the complete removal.
|
||||||
try {
|
try {
|
||||||
ctx.handler().handlerRemoved(ctx);
|
ctx.handler().handlerRemoved(ctx);
|
||||||
if (!tearDown) {
|
ctx.setRemoved();
|
||||||
ctx.setRemoved();
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
fireExceptionCaught(new ChannelPipelineException(
|
fireExceptionCaught(new ChannelPipelineException(
|
||||||
ctx.handler().getClass().getName() + ".handlerRemoved() has thrown an exception.", t));
|
ctx.handler().getClass().getName() + ".handlerRemoved() has thrown an exception.", t));
|
||||||
|
Loading…
Reference in New Issue
Block a user