/** Executed when the I/O has completed */ @Override @SuppressWarnings("unchecked") public void completed(int bytesTransferred, boolean canInvokeDirect) { if (bytesTransferred == 0) { bytesTransferred = -1; // EOF } else { updateBuffers(bytesTransferred); } // return direct buffer to cache if substituted releaseBuffers(); // release waiters if not already released by timeout synchronized (result) { if (result.isDone()) return; enableReading(); if (scatteringRead) { result.setResult((V) Long.valueOf(bytesTransferred)); } else { result.setResult((V) Integer.valueOf(bytesTransferred)); } } if (canInvokeDirect) { Invoker.invokeUnchecked(result); } else { Invoker.invoke(result); } }
/** Invoked if timeout expires before it is cancelled */ void timeout() { // synchronize on result as the I/O could complete/fail synchronized (result) { if (result.isDone()) return; // kill further writing before releasing waiters enableWriting(true); result.setFailure(new InterruptedByTimeoutException()); } // invoke handler without any locks Invoker.invoke(result); }
@Override public void failed(int error, IOException x) { // return direct buffer to cache if substituted releaseBuffers(); // release waiters if not already released by timeout if (!isOpen()) x = new AsynchronousCloseException(); synchronized (result) { if (result.isDone()) return; enableWriting(); result.setFailure(x); } Invoker.invoke(result); }