/** 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); } }
@Override @SuppressWarnings("unchecked") public void run() { long overlapped = 0L; boolean prepared = false; boolean pending = false; try { begin(); // substitute non-direct buffers prepareBuffers(); prepared = true; // get an OVERLAPPED structure (from the cache or allocate) overlapped = ioCache.add(result); // initiate read int n = read0(handle, numBufs, readBufferArray, overlapped); if (n == IOStatus.UNAVAILABLE) { // I/O is pending pending = true; return; } if (n == IOStatus.EOF) { // input shutdown enableReading(); if (scatteringRead) { result.setResult((V) Long.valueOf(-1L)); } else { result.setResult((V) Integer.valueOf(-1)); } } else { throw new InternalError("Read completed immediately"); } } catch (Throwable x) { // failed to initiate read // reset read flag before releasing waiters enableReading(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); if (!(x instanceof IOException)) x = new IOException(x); result.setFailure(x); } finally { // release resources if I/O not pending if (!pending) { if (overlapped != 0L) ioCache.remove(overlapped); if (prepared) releaseBuffers(); } end(); } // invoke completion handler Invoker.invoke(result); }
/** Invoked by handler thread when connection established. */ @Override public void completed(int bytesTransferred, boolean canInvokeDirect) { Throwable exc = null; try { begin(); afterConnect(); result.setResult(null); } catch (Throwable x) { // channel is closed or unable to finish connect exc = x; } finally { end(); } // can't close channel while in begin/end block if (exc != null) { closeChannel(); result.setFailure(toIOException(exc)); } if (canInvokeDirect) { Invoker.invokeUnchecked(result); } else { Invoker.invoke(result); } }
/** Task to initiate a connection. */ @Override public void run() { long overlapped = 0L; Throwable exc = null; try { begin(); // synchronize on result to allow this thread handle the case // where the connection is established immediately. synchronized (result) { overlapped = ioCache.add(result); // initiate the connection int n = connect0( handle, Net.isIPv6Available(), remote.getAddress(), remote.getPort(), overlapped); if (n == IOStatus.UNAVAILABLE) { // connection is pending return; } // connection established immediately afterConnect(); result.setResult(null); } } catch (Throwable x) { if (overlapped != 0L) ioCache.remove(overlapped); exc = x; } finally { end(); } if (exc != null) { closeChannel(); result.setFailure(toIOException(exc)); } Invoker.invoke(result); }