Buffers the write until either {@link #writeBufferedAndRemove(ChannelHandlerContext)} is
called, or we have somehow failed. If we have already failed in the past, then the write
will fail immediately.
334076
@Override
  @SuppressWarnings("FutureReturnValueIgnored")
  public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
    if (failCause != null) {
      promise.setFailure(failCause);
      ReferenceCountUtil.release(msg);
    } else {
      bufferedWrites.add(new ChannelWrite(msg, promise));
    }
  }
1091357
public void close() throws IOException {   
    if (closed) {
      checkWriteThread();
      return;
    }
    try {
      buffer.close(); 
      // writeThread should exit after this
      // and close underlying stream
      try {
        writeThread.join();
      } catch (InterruptedException e) {
        throw new IOException(e);
      }
    } finally {
      checkWriteThread();
    }
  }
859470
public void write() {
    // We record the start time to avoid spending too much time on writings
    long startOfCycle = System.nanoTime();
    long bytesWritten = 0;

    long nPacketsWritten = 0;

    while ((System.nanoTime() - startOfCycle - writeBatchTime.toNanos()) < 0
        && (bytesWritten < writeBatchSize.asBytes())) {
      OutgoingPacket outgoingPacket = outgoingPacketsToWrite.peek();
      if (outgoingPacket == null) {
        break;
      }

      int writeState = outgoingPacket.writeToChannel(socketChannel);
      if (writeState > 0) {
        // Partial writing, we would break since we could not write more data on socket.
        // But we have set the next start point of OutgoingPacket
        // Next time when the socket is writable, it will start from that point.
        break;
      } else if (writeState < 0) {
        LOG.severe("Something bad happened while writing to channel");
        selectHandler.handleError(socketChannel);
        return;
      } else {
        // writeState == 0, we fully write a outgoingPacket
        bytesWritten += outgoingPacket.size();
        nPacketsWritten++;

        outgoingPacketsToWrite.remove();
      }
    }

    totalPacketsWritten += nPacketsWritten;
    totalBytesWritten += bytesWritten;

    // Disable writing if there are nothing to send in buffer
    if (getOutstandingPackets() == 0) {
      disableWriting();
    }
  }
1292339
public ChannelFuture removeAndWrite() {
        assert ctx.executor().inEventLoop();
        PendingWrite write = head;
        if (write == null) {
            return null;
        }
        Object msg = write.msg;
        ChannelPromise promise = write.promise;
        recycle(write, true);
        return ctx.write(msg, promise);
    }
713917
private void write(char buf[]) {
        try {
            synchronized (this) {
                ensureOpen();
                // Android-changed: Lazily initialized.
                BufferedWriter textOut = getTextOut();
                textOut.write(buf);
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush) {
                    for (int i = 0; i < buf.length; i++)
                        if (buf[i] == '\n')
                            out.flush();
                }
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
1366588
@Override
  public void closeWrite() throws IOException
  {
    if (_isWriteClosed) {
      return;
    }
    
    _isWriteClosed = true;
    
    SocketStream stream = _streamImpl;
    
    if (stream != null) {
      stream.closeWrite();
    }
    else if (_s != null) {
      try {
        _s.shutdownOutput();
      } catch (UnsupportedOperationException e) {
        log.log(Level.FINEST, e.toString(), e);
      } catch (Exception e) {
        log.finer(e.toString());
        log.log(Level.FINEST, e.toString(), e);
      }
    }
  }
550553
@Override
    public void flushBuffer() throws IOException {
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
            Tr.debug(tc, "Flushing buffers: " + this);
        }
        if (null != this.outWriter) {
            this.outWriter.flush();
        } else {
            this.outStream.flush();
        }
    }
1208212
public void postProcessWriteBuffers(long dataWritten) {

        if (getByteBufferArrayDirect() == null) {
            try {
                // see if we should post process just the one buffer case
                if (((WsByteBufferImpl) getBuffer()).oWsBBDirect != null) {
                    ((WsByteBufferImpl) getBuffer()).setParmsFromDirectBuffer();
                }
            } catch (ClassCastException cce) {
                // Nothing to do here, already flagged this condition on the
                // pre-processing
            }
            return;
        }

        WsByteBuffer wsBuffArray[] = getBuffers();
        for (int i = 0; i < wsBuffArray.length; i++) {
            if (wsBuffArray[i] == null) {
                break;
            }
            try {
                ((WsByteBufferImpl) wsBuffArray[i]).setParmsFromDirectBuffer();
            } catch (ClassCastException cce) {
                // Nothing to do here, already flagged this condition on the
                // pre-processing
                return;
            }

        }
    }
605289
function write (buffer, cb) {
		if (isStopped) return false

		//test if we have to end
		//FIXME it should wait till all the data fed
		if (buffer == null) {
			callbackQueue.push(function () {
				end()
				cb && cb()
			})
			callbackMarks.push(count)
			return null
		}

		//push buffer
		if (!isAudioBuffer(buffer)) {
			buffer = createBuffer(buffer, {
				channels,
				context
			})
		}

		count += buffer.length
		data.append(buffer)

		//save callback
		if (cb) {
			callbackQueue.push(cb)
			callbackMarks.push(count)
		}

		return buffer
	}
790314
function write (buffer, cb) {
		if (isStopped) return;

		if (buffer == null) {
			return write.end()
		}
		else {
			push(buffer)
		}
		release = cb;
	}
1194287
public void writeTo(SocketChannel channel) throws IOException {
        channel.write(buffer);

        // only if buffer is empty
        if (buffer.remaining() == 0) {
            buffer.clear();
            state = BufferState.READY_TO_WRITE;
        }
    }
6716
private static void writeAndFlush(
      final ByteBuffer buffer, final OutputStream outputStream) throws IOException {

    if (buffer.hasArray()) {
      outputStream.write(buffer.array(), buffer.position(), buffer.remaining());
    } else {
      // cannot access underlying byte array, need to copy into a temporary array
      while (buffer.hasRemaining()) {
        // figure out how much to read, but use an upper limit of 8kb. LogMessages should be rather
        // small so we don't expect this to get hit but avoid large temporary buffers, just in case.
        final int size = Math.min(buffer.remaining(), 8 * 1024);
        final byte[] chunk = new byte[size];
        buffer.get(chunk);
        outputStream.write(chunk);
      }
    }
    outputStream.flush();
  }
922087
@Override
    public void write(ByteBuffer buffer) {
//        if (obj instanceof Persistable)
//            ((Persistable) obj).write(buffer);
//        else {
        if (obj != null)
            buffer.put(getSerialized());
        tmpBuffer = null;
//        }
    }
174820
public ChannelFuture removeAndWriteAll() {
        assert ctx.executor().inEventLoop();

        if (isEmpty()) {
            return null;
        }

        ChannelPromise p = ctx.newPromise();
        PromiseCombiner combiner = new PromiseCombiner(ctx.executor());
        try {
            // It is possible for some of the written promises to trigger more writes. The new writes
            // will "revive" the queue, so we need to write them up until the queue is empty.
            for (PendingWrite write = head; write != null; write = head) {
                head = tail = null;
                size = 0;
                bytes = 0;

                while (write != null) {
                    PendingWrite next = write.next;
                    Object msg = write.msg;
                    ChannelPromise promise = write.promise;
                    recycle(write, false);
                    if (!(promise instanceof VoidChannelPromise)) {
                        combiner.add(promise);
                    }
                    ctx.write(msg, promise);
                    write = next;
                }
            }
            combiner.finish(p);
        } catch (Throwable cause) {
            p.setFailure(cause);
        }
        assertEmpty();
        return p;
    }
1058937
public final void writeToBuffer(T t, byte[] buffer) {
        if (t == null) {
            throw new InvalidArgument("cannot write a null");
        } else if (buffer == null) {
            throw new InvalidArgument("cannot write to a null buffer");
        } else if (buffer.length != recordSize) {
            final String fmt = "invalid buffer (%d bytes, expected %d)";
            final String msg = format(fmt, buffer.length, recordSize);
            throw new InvalidArgument(msg);
        }
        writeTo(t, buffer);
    }
490302
public void writeTo( WritableByteChannel channel ) throws IOException {
        int numberOfBytesToWrite = size;
        for (ByteBuffer buffer : buffers) {
            if (buffer == null) {
                // already flushed
                continue;
            }
            int numBytesInBuffer = Math.min(numberOfBytesToWrite, bufferSize);
            buffer.position(numBytesInBuffer);
            buffer.flip();
            channel.write(buffer);
            numberOfBytesToWrite -= numBytesInBuffer;
        }
        buffers.clear();
    }
1150480
public static final long write(WritableByteChannel channel, ByteBuffer[] srcs, int offset, int length) throws IOException
    {
        long res = 0;
        for  (int ii=0;ii<length;ii++)
        {
            ByteBuffer bb = srcs[ii+offset];
            if (bb.hasRemaining())
            {
                res += channel.write(bb);
                if (bb.hasRemaining())
                {
                    break;
                }
            }
        }
        return res;
    }