Skip to content

Commit 73d1f3f

Browse files
committed
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.
1 parent d72b89d commit 73d1f3f

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.jboss.netty.channel.Channels.*;
1919

20+
import java.nio.channels.ClosedChannelException;
2021
import java.util.Queue;
2122

2223
import org.jboss.netty.buffer.ChannelBuffers;
@@ -150,32 +151,40 @@ public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
150151
ctx.sendUpstream(e);
151152
}
152153

153-
private synchronized void discard(ChannelHandlerContext ctx) {
154-
for (;;) {
155-
if (currentEvent == null) {
156-
currentEvent = queue.poll();
157-
}
154+
private void discard(ChannelHandlerContext ctx) {
155+
ClosedChannelException cause = null;
156+
boolean fireExceptionCaught = false;
157+
synchronized (this) {
158+
for (;;) {
159+
if (currentEvent == null) {
160+
currentEvent = queue.poll();
161+
}
158162

159-
if (currentEvent == null) {
160-
break;
161-
}
163+
if (currentEvent == null) {
164+
break;
165+
}
162166

163-
MessageEvent currentEvent = this.currentEvent;
164-
this.currentEvent = null;
167+
MessageEvent currentEvent = this.currentEvent;
168+
this.currentEvent = null;
165169

166-
Object m = currentEvent.getMessage();
167-
if (m instanceof ChunkedInput) {
168-
closeInput((ChunkedInput) m);
170+
Object m = currentEvent.getMessage();
171+
if (m instanceof ChunkedInput) {
172+
closeInput((ChunkedInput) m);
173+
}
169174

170175
// Trigger a ClosedChannelException
171-
Channels.write(
172-
ctx, currentEvent.getFuture(), ChannelBuffers.EMPTY_BUFFER,
173-
currentEvent.getRemoteAddress());
174-
} else {
175-
// Trigger a ClosedChannelException
176-
ctx.sendDownstream(currentEvent);
176+
if (cause == null) {
177+
cause = new ClosedChannelException();
178+
}
179+
currentEvent.getFuture().setFailure(cause);
180+
fireExceptionCaught = true;
181+
182+
currentEvent = null;
177183
}
178-
currentEvent = null;
184+
}
185+
186+
if (fireExceptionCaught) {
187+
Channels.fireExceptionCaught(currentEvent.getChannel(), cause);
179188
}
180189
}
181190

0 commit comments

Comments
 (0)