/** Invoked by handler thread when failed to establish connection. */ @Override public void failed(int error, IOException x) { if (isOpen()) { closeChannel(); result.setFailure(x); } else { result.setFailure(new AsynchronousCloseException()); } 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); } }
@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 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 // @SuppressWarnings("unchecked") public void run() { long overlapped = 0L; boolean prepared = false; boolean pending = false; boolean shutdown = false; try { begin(); // substitute non-direct buffers prepareBuffers(); prepared = true; // get an OVERLAPPED structure (from the cache or allocate) overlapped = ioCache.add(result); int n = write0(handle, numBufs, writeBufferArray, overlapped); if (n == IOStatus.UNAVAILABLE) { // I/O is pending pending = true; return; } if (n == IOStatus.EOF) { // special case for shutdown output shutdown = true; throw new ClosedChannelException(); } // write completed immediately throw new InternalError("Write completed immediately"); } catch (Throwable x) { // write failed. Enable writing before releasing waiters. enableWriting(); if (!shutdown && (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); }
@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); }
/** 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); }