/** * Transfers the data to the socket write buffer (writing that data to the * socket if the buffer fills up using a non-blocking write) until either * all the data has been transferred and space remains in the socket write * buffer or a non-blocking write leaves data in the socket write buffer. * After an incomplete write, any data remaining to be transferred to the * socket write buffer will be copied to the socket write buffer. If the * remaining data is too big for the socket write buffer, the socket write * buffer will be filled and the additional data written to the non-blocking * write buffer. * * @param from The ByteBuffer containing the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeNonBlocking(ByteBuffer from) throws IOException { if (nonBlockingWriteBuffer.isEmpty() && socketBufferHandler.isWriteBufferWritable()) { writeNonBlockingInternal(from); } if (from.remaining() > 0) { // Remaining data must be buffered nonBlockingWriteBuffer.add(from); } }
void add(byte[] buf, int offset, int length) { ByteBufferHolder holder = getByteBufferHolder(length); holder.getBuf().put(buf, offset, length); }
class StreamOutputBuffer implements HttpOutputBuffer, WriteBuffer.Sink { private final WriteBuffer writeBuffer = new WriteBuffer(32 * 1024); private volatile long written = 0; private volatile int streamReservation = 0; if (writeBuffer.isEmpty()) { if (!flushed) { dataLeft = flush(false, block); dataLeft = writeBuffer.write(this, block);
@Override public void completed(Long nBytes, ByteBuffer[] attachment) { writeNotify = false; synchronized (writeCompletionHandler) { if (nBytes.longValue() < 0) { failed(new EOFException(sm.getString("iob.failedwrite")), attachment); } else if (!nonBlockingWriteBuffer.isEmpty() || arrayHasData(attachment)) { // Continue writing data using a gathering write nestedWriteCompletionCount.get().incrementAndGet(); ByteBuffer[] array = nonBlockingWriteBuffer.toArray(attachment); getSocket().write(array, 0, array.length, toNio2Timeout(getWriteTimeout()), TimeUnit.MILLISECONDS, array, gatheringWriteCompletionHandler); nestedWriteCompletionCount.get().decrementAndGet(); } else { // All data has been written if (writeInterest) { writeInterest = false; writeNotify = true; } writePending.release(); } } if (writeNotify && nestedWriteCompletionCount.get().get() == 0) { endpoint.processSocket(Nio2SocketWrapper.this, SocketEvent.OPEN_WRITE, Nio2Endpoint.isInline()); } }
public boolean hasDataToWrite() { return !socketBufferHandler.isWriteBufferEmpty() || !nonBlockingWriteBuffer.isEmpty(); }
protected final WriteBuffer nonBlockingWriteBuffer = new WriteBuffer(bufferedWriteSize);
if (nBytes.intValue() < 0) { failed(new EOFException(sm.getString("iob.failedwrite")), attachment); } else if (!nonBlockingWriteBuffer.isEmpty()) { nestedWriteCompletionCount.get().incrementAndGet(); ByteBuffer[] array = nonBlockingWriteBuffer.toArray(attachment); getSocket().write(array, 0, array.length, toNio2Timeout(getWriteTimeout()), TimeUnit.MILLISECONDS,
public boolean canWrite() { if (socketBufferHandler == null) { throw new IllegalStateException(sm.getString("socket.closed")); } return socketBufferHandler.isWriteBufferWritable() && nonBlockingWriteBuffer.isEmpty(); }
private class VectoredIOCompletionHandler<A> implements CompletionHandler<Long, OperationState<A>> { @Override public void completed(Long nBytes, OperationState<A> state) { if (nBytes.longValue() < 0) { failed(new EOFException(), state); } else { state.nBytes += nBytes.longValue(); CompletionState currentState = Nio2Endpoint.isInline() ? CompletionState.INLINE : CompletionState.DONE; boolean complete = true; boolean completion = true; if (state.check != null) { switch (state.check.callHandler(currentState, state.buffers, state.offset, state.length)) { case CONTINUE: complete = false; break; case DONE: break; case NONE: completion = false; break; } } if (complete) { boolean notify = false; state.semaphore.release(); if (state.block == BlockingMode.BLOCK && currentState != CompletionState.INLINE) { notify = true; } else { state.state = currentState; }
private boolean flushNonBlocking(boolean hasPermit) throws IOException { checkError(); synchronized (writeCompletionHandler) { if (hasPermit || writePending.tryAcquire()) { socketBufferHandler.configureWriteBufferForRead(); if (!nonBlockingWriteBuffer.isEmpty()) { ByteBuffer[] array = nonBlockingWriteBuffer.toArray(socketBufferHandler.getWriteBuffer()); Nio2Endpoint.startInline(); getSocket().write(array, 0, array.length, toNio2Timeout(getWriteTimeout()), TimeUnit.MILLISECONDS, array, gatheringWriteCompletionHandler); Nio2Endpoint.endInline(); } else if (socketBufferHandler.getWriteBuffer().hasRemaining()) { // Regular write Nio2Endpoint.startInline(); getSocket().write(socketBufferHandler.getWriteBuffer(), toNio2Timeout(getWriteTimeout()), TimeUnit.MILLISECONDS, socketBufferHandler.getWriteBuffer(), writeCompletionHandler); Nio2Endpoint.endInline(); } else { // Nothing was written if (!hasPermit) { writePending.release(); } } } return hasDataToWrite(); } }
protected boolean flushNonBlocking() throws IOException { boolean dataLeft = !socketBufferHandler.isWriteBufferEmpty(); // Write to the socket, if there is anything to write if (dataLeft) { doWrite(false); dataLeft = !socketBufferHandler.isWriteBufferEmpty(); } if (!dataLeft && !nonBlockingWriteBuffer.isEmpty()) { dataLeft = nonBlockingWriteBuffer.write(this, false); if (!dataLeft && !socketBufferHandler.isWriteBufferEmpty()) { doWrite(false); dataLeft = !socketBufferHandler.isWriteBufferEmpty(); } } return dataLeft; }
@Override public boolean hasDataToWrite() { synchronized (writeCompletionHandler) { return !socketBufferHandler.isWriteBufferEmpty() || !nonBlockingWriteBuffer.isEmpty() || getError() != null; } }
public void add(ByteBuffer from) { ByteBufferHolder holder = getByteBufferHolder(from.remaining()); holder.getBuf().put(from); }
final synchronized boolean isReady() { if (getWindowSize() > 0 && handler.getWindowSize() > 0 && writeBuffer.isEmpty()) { return true; } else { return false; } }