@Override public void truncateWrites() throws IOException { for (Frame frame : frameQueue) { FrameCallBack cb = frame.callback; if (cb != null) { cb.failed(UndertowMessages.MESSAGES.channelIsClosed()); } } }
private long doWrite(ByteBuffer[] additionalData, int offs, int len) throws IOException { ByteBuffer[] buffers = new ByteBuffer[bufferCount + (additionalData == null ? 0 : len)]; int count = 0; for (Frame frame : frameQueue) { for (int i = frame.offs; i < frame.offs + frame.len; ++i) { buffers[count++] = frame.data[i]; } } long totalData = queuedData; long userData = 0; if (additionalData != null) { for (int i = offs; i < offs + len; ++i) { buffers[count++] = additionalData[i]; userData += additionalData[i].remaining(); } } totalData += userData; try { long written = next.write(buffers, 0, buffers.length); if (written > this.queuedData) { this.queuedData = 0; } else { this.queuedData -= written; } long toAllocate = written; Frame frame = frameQueue.peek(); while (frame != null) { if (frame.remaining > toAllocate) { frame.remaining -= toAllocate; return 0; } else { frameQueue.poll(); // this frame is done, remove it // note that after we start calling done() we can't re-use the buffers[] array // as pooled buffers may have been returned to the pool and re-used FrameCallBack cb = frame.callback; if (cb != null) { cb.done(); } bufferCount -= frame.len; toAllocate -= frame.remaining; } frame = frameQueue.peek(); } return toAllocate; } catch (IOException e) { // on exception we fail every item in the frame queue try { for (Frame frame : frameQueue) { FrameCallBack cb = frame.callback; if (cb != null) { cb.failed(e); } } frameQueue.clear(); bufferCount = 0; queuedData = 0; } finally { throw e; } } }