@Override <A> Future<Void> implConnect( SocketAddress remote, A attachment, CompletionHandler<Void, ? super A> handler) { if (!isOpen()) { Throwable exc = new ClosedChannelException(); if (handler == null) return CompletedFuture.withFailure(exc); Invoker.invoke(this, handler, attachment, null, exc); return null; } InetSocketAddress isa = Net.checkAddress(remote); // permission check SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); // check and update state // ConnectEx requires the socket to be bound to a local address IOException bindException = null; synchronized (stateLock) { if (state == ST_CONNECTED) throw new AlreadyConnectedException(); if (state == ST_PENDING) throw new ConnectionPendingException(); if (localAddress == null) { try { bind(new InetSocketAddress(0)); } catch (IOException x) { bindException = x; } } if (bindException == null) state = ST_PENDING; } // handle bind failure if (bindException != null) { try { close(); } catch (IOException ignore) { } if (handler == null) return CompletedFuture.withFailure(bindException); Invoker.invoke(this, handler, attachment, null, bindException); return null; } // setup task PendingFuture<Void, A> result = new PendingFuture<Void, A>(this, handler, attachment); ConnectTask task = new ConnectTask<A>(isa, result); result.setContext(task); // initiate I/O if (Iocp.supportsThreadAgnosticIo()) { task.run(); } else { Invoker.invokeOnThreadInThreadPool(this, task); } return result; }
@Override <V extends Number, A> Future<V> implWrite( boolean gatheringWrite, ByteBuffer src, ByteBuffer[] srcs, long timeout, TimeUnit unit, A attachment, CompletionHandler<V, ? super A> handler) { // setup task PendingFuture<V, A> result = new PendingFuture<V, A>(this, handler, attachment); ByteBuffer[] bufs; if (gatheringWrite) { bufs = srcs; } else { bufs = new ByteBuffer[1]; bufs[0] = src; } final WriteTask writeTask = new WriteTask<V, A>(bufs, gatheringWrite, result); result.setContext(writeTask); // schedule timeout if (timeout > 0L) { Future<?> timeoutTask = iocp.schedule( new Runnable() { public void run() { writeTask.timeout(); } }, timeout, unit); result.setTimeoutTask(timeoutTask); } // initiate I/O (can only be done from thread in thread pool) // initiate I/O if (Iocp.supportsThreadAgnosticIo()) { writeTask.run(); } else { Invoker.invokeOnThreadInThreadPool(this, writeTask); } return result; }
@Override <V extends Number, A> Future<V> implRead( boolean isScatteringRead, ByteBuffer dst, ByteBuffer[] dsts, long timeout, TimeUnit unit, A attachment, CompletionHandler<V, ? super A> handler) { // setup task PendingFuture<V, A> result = new PendingFuture<V, A>(this, handler, attachment); ByteBuffer[] bufs; if (isScatteringRead) { bufs = dsts; } else { bufs = new ByteBuffer[1]; bufs[0] = dst; } final ReadTask readTask = new ReadTask<V, A>(bufs, isScatteringRead, result); result.setContext(readTask); // schedule timeout if (timeout > 0L) { Future<?> timeoutTask = iocp.schedule( new Runnable() { public void run() { readTask.timeout(); } }, timeout, unit); result.setTimeoutTask(timeoutTask); } // initiate I/O if (Iocp.supportsThreadAgnosticIo()) { readTask.run(); } else { Invoker.invokeOnThreadInThreadPool(this, readTask); } return result; }