@Override public void registerReadInterest() { synchronized (readCompletionHandler) { if (readPending.availablePermits() == 0) { readInterest = true; } else { // If no read is pending, start waiting for data awaitBytes(); } } }
@Override public int read(boolean block, ByteBuffer to) throws IOException { checkError(); int nRead = populateReadBuffer(to); if (nRead > 0) { if (block && to.remaining() >= limit) { to.limit(to.position() + limit); nRead = fillReadBuffer(block, to); if (log.isDebugEnabled()) { log.debug("Socket: [" + this + "], Read direct from socket: [" + nRead + "]"); nRead = fillReadBuffer(block); if (log.isDebugEnabled()) { log.debug("Socket: [" + this + "], Read into buffer: [" + nRead + "]"); nRead = populateReadBuffer(to); } else if (nRead == 0 && !block) { readInterest = true;
@Override public void completed(Integer nBytes, SocketWrapperBase<Nio2Channel> attachment) { boolean notify = false; if (log.isDebugEnabled()) { log.debug("Socket: [" + attachment + "], Interest: [" + readInterest + "]"); } synchronized (readCompletionHandler) { if (nBytes.intValue() < 0) { failed(new EOFException(), attachment); } else { if (readInterest && !Nio2Endpoint.isInline()) { readInterest = false; notify = true; } else { // Release here since there will be no // notify/dispatch to do the release. readPending.release(); } } } if (notify) { getEndpoint().processSocket(attachment, SocketEvent.OPEN_READ, false); } } @Override
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; }
BlockingMode block, long timeout, TimeUnit unit, A attachment, CompletionCheck check, CompletionHandler<Long, ? super A> handler) { IOException ioe = getError(); if (ioe != null) { handler.failed(ioe, attachment); timeout = toNio2Timeout(getReadTimeout()); nBytes += transfer(socketBufferHandler.getReadBuffer(), dsts[offset + i]); getSocket().read(dsts, offset, length, timeout, unit, state, completion);
ByteBuffer buffer = getSocket().getBufHandler().getWriteBuffer(); if (!buffer.hasRemaining()) { if (attachment.length <= 0) { setSendfileData(null); try { attachment.fchannel.close(); switch (attachment.keepAliveState) { case NONE: { getEndpoint().processSocket(Nio2SocketWrapper.this, SocketEvent.DISCONNECT, false); break; getEndpoint().processSocket(Nio2SocketWrapper.this, SocketEvent.OPEN_READ, true); break; awaitBytes(); break; getSocket().getBufHandler().configureWriteBufferForWrite(); int nRead = -1; try { getSocket().getBufHandler().configureWriteBufferForRead(); if (attachment.length < buffer.remaining()) { buffer.limit(buffer.limit() - buffer.remaining() + (int) attachment.length);
BlockingMode block, long timeout, TimeUnit unit, A attachment, CompletionCheck check, CompletionHandler<Long, ? super A> handler) { IOException ioe = getError(); if (ioe != null) { handler.failed(ioe, attachment); timeout = toNio2Timeout(getWriteTimeout()); doWrite(true); } catch (IOException e) { handler.failed(e, attachment); Nio2Endpoint.startInline(); getSocket().write(srcs, offset, length, timeout, unit, state, completion); Nio2Endpoint.endInline(); if (block == BlockingMode.BLOCK) {
@Override public int read(boolean block, byte[] b, int off, int len) throws IOException { checkError(); int nRead = populateReadBuffer(b, off, len); if (nRead > 0) { nRead = fillReadBuffer(block);
if (block) { try { integer = getSocket().read(to); long timeout = getReadTimeout(); if (timeout > 0) { nRead = integer.get(timeout, TimeUnit.MILLISECONDS).intValue(); getSocket().read(to, toNio2Timeout(getReadTimeout()), TimeUnit.MILLISECONDS, this, readCompletionHandler); Nio2Endpoint.endInline();
Nio2SocketWrapper socketWrapper = new Nio2SocketWrapper(channel, this); channel.reset(socket, socketWrapper); socketWrapper.setReadTimeout(getConnectionTimeout()); socketWrapper.setWriteTimeout(getConnectionTimeout()); socketWrapper.setKeepAliveLeft(Nio2Endpoint.this.getMaxKeepAliveRequests()); socketWrapper.setSecure(isSSLEnabled());
if (nio2Socket.getSendfileData() != null && nio2Socket.getSendfileData().fchannel != null && nio2Socket.getSendfileData().fchannel.isOpen()) { nio2Socket.getSendfileData().fchannel.close();
transfer(from, socketBufferHandler.getWriteBuffer()); if (from.remaining() > 0) { flushNonBlocking(true); } else { nonBlockingWriteBuffer.add(from);
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(); } }
@Override public boolean isReadyForRead() throws IOException { synchronized (readCompletionHandler) { if (!readPending.tryAcquire()) { readInterest = true; return false; } if (!socketBufferHandler.isReadBufferEmpty()) { readPending.release(); return true; } int nRead = fillReadBuffer(false); boolean isReady = nRead > 0; if (!isReady) { readInterest = true; } return isReady; } }
@Override public void failed(Throwable exc, SocketWrapperBase<Nio2Channel> attachment) { IOException ioe; if (exc instanceof IOException) { ioe = (IOException) exc; } else { ioe = new IOException(exc); } setError(ioe); if (exc instanceof AsynchronousCloseException) { // Release here since there will be no // notify/dispatch to do the release. readPending.release(); // If already closed, don't call onError and close again return; } getEndpoint().processSocket(attachment, SocketEvent.ERROR, true); } };
@Override protected void flushBlocking() throws IOException { checkError(); // Before doing a blocking flush, make sure that any pending non // blocking write has completed. try { if (writePending.tryAcquire(toNio2Timeout(getWriteTimeout()), TimeUnit.MILLISECONDS)) { writePending.release(); } else { throw new SocketTimeoutException(); } } catch (InterruptedException e) { // Ignore } super.flushBlocking(); }
@Override public void failed(Throwable exc, SendfileData attachment) { try { attachment.fchannel.close(); } catch (IOException e) { // Ignore } if (!isInline()) { getEndpoint().processSocket(Nio2SocketWrapper.this, SocketEvent.ERROR, false); } else { attachment.doneInline = true; attachment.error = true; } } };
/** * {@inheritDoc} * @param clientCertProvider Ignored for this implementation */ @Override public SSLSupport getSslSupport(String clientCertProvider) { if (getSocket() instanceof SecureNio2Channel) { SecureNio2Channel ch = (SecureNio2Channel) getSocket(); SSLSession session = ch.getSslEngine().getSession(); return ((Nio2Endpoint) getEndpoint()).getSslImplementation().getSSLSupport(session); } else { return null; } }
@Override protected boolean flushNonBlocking() throws IOException { return flushNonBlocking(false); }
private int fillReadBuffer(boolean block) throws IOException { socketBufferHandler.configureReadBufferForWrite(); return fillReadBuffer(block, socketBufferHandler.getReadBuffer()); }