/** {@inheritDoc} */ @Override public AsyncSocketChannelImpl shutdown(ShutdownType how) throws IOException { final Socket socket = channel.socket(); try { if (how == ShutdownType.READ || how == ShutdownType.BOTH) { if (!socket.isInputShutdown()) { socket.shutdownInput(); key.selected(OP_READ); } } if (how == ShutdownType.WRITE || how == ShutdownType.BOTH) { if (!socket.isOutputShutdown()) { socket.shutdownOutput(); key.selected(OP_WRITE); } } } catch (SocketException e) { if (!socket.isConnected()) { throw Util.initCause(new NotYetConnectedException(), e); } if (socket.isClosed()) { throw Util.initCause(new ClosedChannelException(), e); } throw e; } return this; }
/** {@inheritDoc} */ @Override public <A> IoFuture<Void, A> connect( SocketAddress remote, final A attachment, final CompletionHandler<Void, ? super A> handler) { try { if (channel.connect(remote)) { Future<Void> result = Util.finishedFuture(null); key.runCompletion(handler, attachment, result); return AttachedFuture.wrap(result, attachment); } } catch (ClosedChannelException e) { throw Util.initCause(new ClosedAsynchronousChannelException(), e); } catch (IOException e) { Future<Void> result = Util.failedFuture(e); key.runCompletion(handler, attachment, result); return AttachedFuture.wrap(result, attachment); } return key.execute( OP_CONNECT, attachment, handler, 0, TimeUnit.MILLISECONDS, new Callable<Void>() { public Void call() throws IOException { try { channel.finishConnect(); return null; } catch (ClosedChannelException e) { throw Util.initCause(new AsynchronousCloseException(), e); } } }); }
/** {@inheritDoc} */ @Override public <A> IoFuture<Long, A> write( final ByteBuffer[] srcs, final int offset, final int length, long timeout, TimeUnit unit, A attachment, CompletionHandler<Long, ? super A> handler) { if ((offset < 0) || (offset >= srcs.length)) { throw new IllegalArgumentException("offset out of range"); } if ((length < 0) || (length > (srcs.length - offset))) { throw new IllegalArgumentException("length out of range"); } return key.execute( OP_WRITE, attachment, handler, timeout, unit, new Callable<Long>() { public Long call() throws IOException { try { return channel.write(srcs, offset, length); } catch (ClosedChannelException e) { throw Util.initCause(new AsynchronousCloseException(), e); } } }); }
/** {@inheritDoc} */ @Override public <A> IoFuture<Integer, A> read( final ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler) { if (timeout == 0) { timeout = socketTimeout; unit = TimeUnit.MILLISECONDS; } return key.execute( OP_READ, attachment, handler, timeout, unit, new Callable<Integer>() { public Integer call() throws IOException { try { return channel.read(dst); } catch (ClosedChannelException e) { throw Util.initCause(new AsynchronousCloseException(), e); } } }); }
/** {@inheritDoc} */ @Override public <A> IoFuture<Integer, A> write( final ByteBuffer src, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler) { return key.execute( OP_WRITE, attachment, handler, timeout, unit, new Callable<Integer>() { public Integer call() throws IOException { try { return channel.write(src); } catch (ClosedChannelException e) { throw Util.initCause(new AsynchronousCloseException(), e); } } }); }
/** {@inheritDoc} */ @Override public <A> IoFuture<AsynchronousSocketChannel, A> accept( A attachment, CompletionHandler<AsynchronousSocketChannel, ? super A> handler) { return key.execute( OP_ACCEPT, attachment, handler, 0, TimeUnit.MILLISECONDS, new Callable<AsynchronousSocketChannel>() { public AsynchronousSocketChannel call() throws IOException { try { SocketChannel newChannel = channel.accept(); if (newChannel == null) { // TODO re-execute on the key somehow? -JM throw new IOException("accept failed"); } return new AsyncSocketChannelImpl(group, newChannel); } catch (ClosedChannelException e) { throw Util.initCause(new AsynchronousCloseException(), e); } } }); }
/** {@inheritDoc} */ @Override public boolean isWritePending() { return key.isOpPending(OP_WRITE); }
/** {@inheritDoc} */ @Override public boolean isReadPending() { return key.isOpPending(OP_READ); }
/** {@inheritDoc} */ @Override public void close() throws IOException { key.close(); }
/** {@inheritDoc} */ @Override public boolean isAcceptPending() { return key.isOpPending(OP_ACCEPT); }