Make sure handlerAdded() is called before forwarding the buffer content of the removed handler
- Added a test case that reproduces the problem in ReplayingDecoderTest - Call newHandler.handlerAdded() *before* oldHandler.handlerRemoved() to ensure newHandlerAdded() is called before forwarding the buffer content of the old handler in replace0().
This commit is contained in:
parent
99b999760a
commit
1b3d7f5325
@ -22,7 +22,6 @@ import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundByteHandlerAdapter;
|
||||
import io.netty.channel.embedded.EmbeddedByteChannel;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@ -65,7 +64,6 @@ public class ReplayingDecoderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("needs a fix")
|
||||
public void testReplacement() throws Exception {
|
||||
EmbeddedByteChannel ch = new EmbeddedByteChannel(new BloatedLineDecoder());
|
||||
|
||||
|
@ -442,25 +442,32 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
return ctx.handler();
|
||||
}
|
||||
|
||||
private void replace0(DefaultChannelHandlerContext ctx, String newName,
|
||||
private void replace0(DefaultChannelHandlerContext oldCtx, String newName,
|
||||
DefaultChannelHandlerContext newCtx) {
|
||||
checkMultiplicity(newCtx);
|
||||
|
||||
DefaultChannelHandlerContext prev = ctx.prev;
|
||||
DefaultChannelHandlerContext next = ctx.next;
|
||||
DefaultChannelHandlerContext prev = oldCtx.prev;
|
||||
DefaultChannelHandlerContext next = oldCtx.next;
|
||||
newCtx.prev = prev;
|
||||
newCtx.next = next;
|
||||
|
||||
// Finish the replacement of oldCtx with newCtx in the linked list.
|
||||
// Note that this doesn't mean events will be sent to the new handler immediately
|
||||
// because we are currently at the event handler thread and no more than one handler methods can be invoked
|
||||
// at the same time (we ensured that in replace().)
|
||||
prev.next = newCtx;
|
||||
next.prev = newCtx;
|
||||
|
||||
if (!ctx.name().equals(newName)) {
|
||||
name2ctx.remove(ctx.name());
|
||||
if (!oldCtx.name().equals(newName)) {
|
||||
name2ctx.remove(oldCtx.name());
|
||||
}
|
||||
name2ctx.put(newName, newCtx);
|
||||
|
||||
// remove old and add new
|
||||
callHandlerRemoved(ctx, newCtx, newCtx);
|
||||
// Invoke newHandler.handlerAdded() first (i.e. before oldHandler.handlerRemoved() is invoked)
|
||||
// because callHandlerRemoved() will trigger inboundBufferUpdated() or flush() on newHandler and those
|
||||
// event handlers must be called after handlerAdded().
|
||||
callHandlerAdded(newCtx);
|
||||
callHandlerRemoved(oldCtx, newCtx, newCtx);
|
||||
}
|
||||
|
||||
private static void checkMultiplicity(ChannelHandlerContext ctx) {
|
||||
|
Loading…
Reference in New Issue
Block a user