Fixed a problem where ClosedChannelException is raised when SslHandler sends a closure_notify

This commit is contained in:
Trustin Lee 2009-04-15 15:28:30 +00:00
parent e323b221d7
commit 1262c45ab3

View File

@ -138,6 +138,7 @@ public class SslHandler extends FrameDecoder {
private final AtomicBoolean sentFirstMessage = new AtomicBoolean(); private final AtomicBoolean sentFirstMessage = new AtomicBoolean();
private final AtomicBoolean sentCloseNotify = new AtomicBoolean(); private final AtomicBoolean sentCloseNotify = new AtomicBoolean();
final AtomicBoolean ignoreClosedChannelException = new AtomicBoolean();
private final Queue<PendingWrite> pendingUnencryptedWrites = new LinkedList<PendingWrite>(); private final Queue<PendingWrite> pendingUnencryptedWrites = new LinkedList<PendingWrite>();
private final Queue<MessageEvent> pendingEncryptedWrites = new LinkedList<MessageEvent>(); private final Queue<MessageEvent> pendingEncryptedWrites = new LinkedList<MessageEvent>();
@ -382,19 +383,28 @@ public class SslHandler extends FrameDecoder {
throws Exception { throws Exception {
Throwable cause = e.getCause(); Throwable cause = e.getCause();
if (cause instanceof IOException && engine.isOutboundDone()) { if (cause instanceof IOException) {
String message = String.valueOf(cause.getMessage()).toLowerCase(); if (cause instanceof ClosedChannelException) {
if (CONNECTION_RESET.matcher(message).matches()) { if (ignoreClosedChannelException.compareAndSet(true, false)) {
// It is safe to ignore the 'connection reset by peer' error logger.debug(
// after sending closure_notify. "Swallowing an exception raised while writing " +
logger.debug( "'closure_notify'", cause);
"Ignoring a 'connection reset by peer' error", return;
cause); }
} else if (engine.isOutboundDone()) {
String message = String.valueOf(cause.getMessage()).toLowerCase();
if (CONNECTION_RESET.matcher(message).matches()) {
// It is safe to ignore the 'connection reset by peer' error
// after sending closure_notify.
logger.debug(
"Swallowing a 'connection reset by peer' error " +
"occurred while writing 'closure_notify'", cause);
// Close the connection explicitly just in case the transport // Close the connection explicitly just in case the transport
// did not close the connection automatically. // did not close the connection automatically.
Channels.close(ctx, succeededFuture(e.getChannel())); Channels.close(ctx, succeededFuture(e.getChannel()));
return; return;
}
} }
} }
@ -781,7 +791,11 @@ public class SslHandler extends FrameDecoder {
ChannelFuture closeNotifyFuture = wrapNonAppData(context, e.getChannel()); ChannelFuture closeNotifyFuture = wrapNonAppData(context, e.getChannel());
closeNotifyFuture.addListener(new ChannelFutureListener() { closeNotifyFuture.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture closeNotifyFuture) throws Exception { public void operationComplete(ChannelFuture closeNotifyFuture) throws Exception {
Channels.close(context, e.getFuture()); if (closeNotifyFuture.getCause() instanceof ClosedChannelException) {
ignoreClosedChannelException.set(true);
} else {
Channels.close(context, e.getFuture());
}
} }
}); });
return; return;