Do not write if connect incomplete (#44466)

Currently, we do not handle READ or WRITE events until the channel
connection process is complete. However, the external write queue path
allows a write to be attempted when the conneciton is not complete. This
commit closes the loophole and only queues write operations when the
connection process is not complete.
This commit is contained in:
Tim Brooks 2019-07-17 10:28:17 -04:00
parent aff66e3ac5
commit fdc6c9853f
No known key found for this signature in database
GPG Key ID: C2AA3BB91A889E77
2 changed files with 15 additions and 5 deletions

View File

@ -359,7 +359,9 @@ public class NioSelector implements Closeable {
}
if (shouldFlushAfterQueuing) {
if (context.selectorShouldClose() == false) {
// We only attempt the write if the connect process is complete and the context is not
// signalling that it should be closed.
if (context.isConnectComplete() && context.selectorShouldClose() == false) {
handleWrite(context);
}
eventHandler.postHandling(context);

View File

@ -355,8 +355,6 @@ public class NioSelectorTests extends ESTestCase {
public void testQueueDirectlyInChannelBufferSuccessful() throws Exception {
WriteOperation writeOperation = new FlushReadyWrite(channelContext, buffers, listener);
assertEquals(0, (selectionKey.interestOps() & SelectionKey.OP_WRITE));
when(channelContext.readyForFlush()).thenReturn(true);
selector.queueWrite(writeOperation);
@ -368,8 +366,6 @@ public class NioSelectorTests extends ESTestCase {
public void testShouldFlushIfNoPendingFlushes() throws Exception {
WriteOperation writeOperation = new FlushReadyWrite(channelContext, buffers, listener);
assertEquals(0, (selectionKey.interestOps() & SelectionKey.OP_WRITE));
when(channelContext.readyForFlush()).thenReturn(false);
selector.queueWrite(writeOperation);
@ -378,6 +374,18 @@ public class NioSelectorTests extends ESTestCase {
verify(eventHandler).postHandling(channelContext);
}
public void testShouldNotFlushIfChannelNotConnectedPendingFlushes() throws Exception {
WriteOperation writeOperation = new FlushReadyWrite(channelContext, buffers, listener);
when(channelContext.readyForFlush()).thenReturn(false);
when(channelContext.isConnectComplete()).thenReturn(false);
selector.queueWrite(writeOperation);
verify(channelContext).queueWriteOperation(writeOperation);
verify(eventHandler, times(0)).handleWrite(channelContext);
verify(eventHandler).postHandling(channelContext);
}
public void testConnectEvent() throws Exception {
selectionKey.setReadyOps(SelectionKey.OP_CONNECT);