@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;
      }
    }
  }