diff -r 4070cecdb99d -r 29d6145d1097 jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java --- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Sun Aug 31 18:32:59 2008 +0100 +++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Sun Aug 31 18:39:01 2008 +0100 @@ -33,8 +33,7 @@ import java.nio.channels.spi.*; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.HashSet; -import java.util.Iterator; +import java.util.*; /** @@ -75,10 +74,7 @@ private int state = ST_UNINITIALIZED; // Binding - private SocketAddress localAddress = null; // null => unbound - - // Options, created on demand - private SocketOpts.IP.TCP options = null; + private SocketAddress localAddress; // null => unbound // Our socket adaptor, if any ServerSocket socket; @@ -103,7 +99,6 @@ localAddress = Net.localAddress(fd); } - public ServerSocket socket() { synchronized (stateLock) { if (socket == null) @@ -112,6 +107,69 @@ } } + @Override + public SocketAddress getLocalAddress() throws IOException { + synchronized (stateLock) { + if (!isOpen()) + return null; + return localAddress; + } + } + + @Override + public ServerSocketChannel setOption(SocketOption name, Object value) + throws IOException + { + if (name == null) + throw new NullPointerException(); + if (!options().contains(name)) + throw new IllegalArgumentException("invalid option name"); + + synchronized (stateLock) { + if (!isOpen()) + throw new ClosedChannelException(); + + // no options that require special handling + Net.setSocketOption(fd, Net.UNSPEC, name, value); + return this; + } + } + + @Override + @SuppressWarnings("unchecked") + public T getOption(SocketOption name) + throws IOException + { + if (name == null) + throw new NullPointerException(); + if (!options().contains(name)) + throw new IllegalArgumentException("invalid option name"); + + synchronized (stateLock) { + if (!isOpen()) + throw new ClosedChannelException(); + + // no options that require special handling + return (T) Net.getSocketOption(fd, Net.UNSPEC, name); + } + } + + private static class LazyInitialization { + static final Set> defaultOptions = defaultOptions(); + + private static Set> defaultOptions() { + HashSet> set = new HashSet>(2); + set.add(StandardSocketOption.SO_RCVBUF); + set.add(StandardSocketOption.SO_REUSEADDR); + return Collections.unmodifiableSet(set); + } + } + + @Override + public final Set> options() { + return LazyInitialization.defaultOptions; + } + public boolean isBound() { synchronized (stateLock) { return localAddress != null; @@ -124,22 +182,25 @@ } } - public void bind(SocketAddress local, int backlog) throws IOException { + @Override + public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException { synchronized (lock) { if (!isOpen()) throw new ClosedChannelException(); if (isBound()) throw new AlreadyBoundException(); - InetSocketAddress isa = Net.checkAddress(local); + InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : + Net.checkAddress(local); SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkListen(isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort()); - listen(fd, backlog < 1 ? 50 : backlog); + Net.listen(fd, backlog < 1 ? 50 : backlog); synchronized (stateLock) { localAddress = Net.localAddress(fd); } } + return this; } public SocketChannel accept() throws IOException { @@ -196,24 +257,6 @@ IOUtil.configureBlocking(fd, block); } - public SocketOpts options() { - synchronized (stateLock) { - if (options == null) { - SocketOptsImpl.Dispatcher d - = new SocketOptsImpl.Dispatcher() { - int getInt(int opt) throws IOException { - return Net.getIntOption(fd, opt); - } - void setInt(int opt, int arg) throws IOException { - Net.setIntOption(fd, opt, arg); - } - }; - options = new SocketOptsImpl.IP.TCP(d); - } - return options; - } - } - protected void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { nd.preClose(fd); @@ -320,9 +363,6 @@ // -- Native methods -- - private static native void listen(FileDescriptor fd, int backlog) - throws IOException; - // Accepts a new connection, setting the given file descriptor to refer to // the new socket and setting isaa[0] to the socket's remote address. // Returns 1 on success, or IOStatus.UNAVAILABLE (if non-blocking and no