private static void writeNow(NioSocketChannel channel, int writeSpinCount) { boolean open = true; boolean addOpWrite = false; boolean removeOpWrite = false; MessageEvent evt; ChannelBuffer buf; int bufIdx; int writtenBytes = 0; Queue<MessageEvent> writeBuffer = channel.writeBuffer; synchronized (channel.writeLock) { channel.inWriteNowLoop = true; evt = channel.currentWriteEvent; for (; ; ) { if (evt == null) { evt = writeBuffer.poll(); if (evt == null) { channel.currentWriteEvent = null; removeOpWrite = true; break; } evt = consolidateComposite(evt); buf = (ChannelBuffer) evt.getMessage(); bufIdx = buf.readerIndex(); } else { buf = (ChannelBuffer) evt.getMessage(); bufIdx = channel.currentWriteIndex; } try { for (int i = writeSpinCount; i > 0; i--) { int localWrittenBytes = buf.getBytes(bufIdx, channel.socket, buf.writerIndex() - bufIdx); if (localWrittenBytes != 0) { bufIdx += localWrittenBytes; writtenBytes += localWrittenBytes; break; } } if (bufIdx == buf.writerIndex()) { // Successful write - proceed to the next message. channel.currentWriteEvent = null; evt.getFuture().setSuccess(); evt = null; } else { // Not written fully - perhaps the kernel buffer is full. channel.currentWriteEvent = evt; channel.currentWriteIndex = bufIdx; addOpWrite = true; break; } } catch (AsynchronousCloseException e) { // Doesn't need a user attention - ignore. channel.currentWriteEvent = evt; channel.currentWriteIndex = bufIdx; } catch (Throwable t) { channel.currentWriteEvent = null; evt.getFuture().setFailure(t); evt = null; fireExceptionCaught(channel, t); if (t instanceof IOException) { open = false; close(channel, succeededFuture(channel)); } } } channel.inWriteNowLoop = false; } fireWriteComplete(channel, writtenBytes); if (open) { if (addOpWrite) { setOpWrite(channel); } else if (removeOpWrite) { clearOpWrite(channel); } } }