NETTY-384 Another deadlock in ChunkedWriteHandler
ChunkedWriteHandler.discard() do not issue write requests to trigger exceptionCaught events and to notify write futures anymore. Instead, it triggers exceptionCaught events and notifies write futures by itself. Therefore, no write lock is involved during discard(), avoiding the reported dead lock. However, this is a temporary solution, and eventually Netty must introduce more robust event thread model.
This commit is contained in:
parent
d72b89db21
commit
73d1f3fe02
@ -17,6 +17,7 @@ package org.jboss.netty.handler.stream;
|
|||||||
|
|
||||||
import static org.jboss.netty.channel.Channels.*;
|
import static org.jboss.netty.channel.Channels.*;
|
||||||
|
|
||||||
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
import org.jboss.netty.buffer.ChannelBuffers;
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
@ -150,32 +151,40 @@ public class ChunkedWriteHandler implements ChannelUpstreamHandler, ChannelDowns
|
|||||||
ctx.sendUpstream(e);
|
ctx.sendUpstream(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void discard(ChannelHandlerContext ctx) {
|
private void discard(ChannelHandlerContext ctx) {
|
||||||
for (;;) {
|
ClosedChannelException cause = null;
|
||||||
if (currentEvent == null) {
|
boolean fireExceptionCaught = false;
|
||||||
currentEvent = queue.poll();
|
synchronized (this) {
|
||||||
}
|
for (;;) {
|
||||||
|
if (currentEvent == null) {
|
||||||
|
currentEvent = queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentEvent == null) {
|
if (currentEvent == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageEvent currentEvent = this.currentEvent;
|
MessageEvent currentEvent = this.currentEvent;
|
||||||
this.currentEvent = null;
|
this.currentEvent = null;
|
||||||
|
|
||||||
Object m = currentEvent.getMessage();
|
Object m = currentEvent.getMessage();
|
||||||
if (m instanceof ChunkedInput) {
|
if (m instanceof ChunkedInput) {
|
||||||
closeInput((ChunkedInput) m);
|
closeInput((ChunkedInput) m);
|
||||||
|
}
|
||||||
|
|
||||||
// Trigger a ClosedChannelException
|
// Trigger a ClosedChannelException
|
||||||
Channels.write(
|
if (cause == null) {
|
||||||
ctx, currentEvent.getFuture(), ChannelBuffers.EMPTY_BUFFER,
|
cause = new ClosedChannelException();
|
||||||
currentEvent.getRemoteAddress());
|
}
|
||||||
} else {
|
currentEvent.getFuture().setFailure(cause);
|
||||||
// Trigger a ClosedChannelException
|
fireExceptionCaught = true;
|
||||||
ctx.sendDownstream(currentEvent);
|
|
||||||
|
currentEvent = null;
|
||||||
}
|
}
|
||||||
currentEvent = null;
|
}
|
||||||
|
|
||||||
|
if (fireExceptionCaught) {
|
||||||
|
Channels.fireExceptionCaught(currentEvent.getChannel(), cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user