Mercurial > hg > release > icedtea7-2.2
changeset 1576:913512a256bd
Fix UNIX sun.nio.ch and shared sun.nio.fs classes.
2009-01-19 Andrew John Hughes <gnu_andrew@member.fsf.org>
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaNetGetIndexAccess.java:
(getByIndex(int)): New method.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java:
Fixed imports.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java,
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java:
New files.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java:
Fix imports, refer to AsynchronousFileLockImpl instead of FileLockImpl.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java:
Fix imports and vararg usage.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java,
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java:
Fix vararg usage.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java,
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java,
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java:
Fix imports.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java:
Fix imports and vararg usage.
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/Port.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java:
Fix imports.
* patches/icedtea-nio2.patch:
Add new classes.
(Unsafe.copyMemory(long,long,long)): Backported.
(Unsafe.copyMemory(Object,long,Object,long,long)): Backported.
(Unsafe.ARRAY_BYTE_BASE_OFFSET): Likewise.
(DatagramChannelImpl.bind(SocketAddress)): Likewise.
(DatagramChannelImpl.getLocalAddress()): Likewise.
(DatagramChannelImpl.getOption(SocketOption)): Likewise.
(DatagramChannelImpl.innerJoin(InetAddress,NetworkInterface,InetAddress)): Likewise.
(DatagramChannelImpl.join(InetAddress,NetworkInterface)): Likewise.
(DatagramChannelImpl.join(InetAddress,NetworkInterface,InetAddress)): Likewise.
(DatagramChannelImpl.block(MembershipKeyImpl,InetAddress)): Likewise.
(DatagramChannelImpl.unblock(MembershipKeyImpl,InetAddress)): Likewise.
(DatagramChannelImpl.drop(MembershipKeyImpl)): Likewise.
(Net.getInterface4(FileDescriptor)): Likewise.
(Net.getInterface6(FileDescriptor)): Likewise.
(Net.inet4FromInt(int)): Likewise.
(Net.inet6AsByteArray(InetAddress)): Likewise.
(Net.join6(FileDescriptor,byte[],int,byte[])): Likewise.
(Net.drop6(FileDescriptor,byte[],int,byte[])): Likewise.
(Net.joinOrDrop6(boolean,FileDescriptor,byte[],int,byte[])): Likewise.
(Net.block6(FileDescriptor,byte[],int,byte[])): Likewise.
(Net.unblock6(FileDescriptor,byte[],int,byte[])): Likewise.
(Net.blockOrUnblock6(boolean,FileDescriptor,byte[],int,byte[])): Likewise.
(Net.join4(FileDescriptor,int,int,int)): Likewise.
(Net.drop4(FileDescriptor,int,int,int)): Likewise.
(Net.joinOrDrop4(boolean,FileDescriptor,int,int,int)): Likewise.
(Net.block4(FileDescriptor,int,int,int)): Likewise.
(Net.unblock4(FileDescriptor,int,int,int)): Likewise.
(Net.blockOrUnblock4(boolean,FileDescriptor,int,int,int)): Likewise.
(Net.connect(FileDescriptor,InetAddress,int)): Likewise.
(Net.connect(ProtocolFamily,FileDescriptor,InetAddress,int)): Likewise.
(Net.connect0(boolean,FileDescriptor,InetAddress,int)): Likewise.
(FileDispatcher.NO_LOCK)): Likewise.
(FileDispatcher.LOCKED)): Likewise.
(FileDispatcher.RET_EX_LOCK)): Likewise.
(FileDispatcher.INTERRUPTED)): Likewise.
(FileDispatcher.size(FileDescriptor)): Likewise.
(FileDispatcher.truncate(FileDescriptor, long)): Likewise.
(FileDispatcher.force(FileDescriptor, boolean)): Likewise.
(FileDispatcher.lock(FileDescriptor, boolean, long, long, boolean)): Likewise.
(FileDispatcher.release(FileDescriptor, long, long)): Likewise.
(FileDispatcher.force0(FileDescriptor,boolean)): Likewise.
(FileDispatcher.truncate0(FileDescriptor, long)): Likewise.
(FileDispatcher.size0(FileDescriptor)): Likewise.
(FileDispatcher.lock0(FileDescriptor, boolean, long, long, boolean)): Likewise.
(FileDispatcher.release0(FileDescriptor, long, long)): Likewise.
line wrap: on
line diff
--- a/ChangeLog Mon Jan 19 14:25:02 2009 +0000 +++ b/ChangeLog Tue Jan 20 00:06:18 2009 +0000 @@ -1,3 +1,79 @@ +2009-01-19 Andrew John Hughes <gnu_andrew@member.fsf.org> + + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaNetGetIndexAccess.java: + (getByIndex(int)): New method. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java: + Fixed imports. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java, + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java: + New files. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java: + Fix imports, refer to AsynchronousFileLockImpl instead of FileLockImpl. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java: + Fix imports and vararg usage. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java, + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java: + Fix vararg usage. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java, + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java, + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java: + Fix imports. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java: + Fix imports and vararg usage. + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/Port.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java: + Fix imports. + * patches/icedtea-nio2.patch: + Add new classes. + (Unsafe.copyMemory(long,long,long)): Backported. + (Unsafe.copyMemory(Object,long,Object,long,long)): Backported. + (Unsafe.ARRAY_BYTE_BASE_OFFSET): Likewise. + (DatagramChannelImpl.bind(SocketAddress)): Likewise. + (DatagramChannelImpl.getLocalAddress()): Likewise. + (DatagramChannelImpl.getOption(SocketOption)): Likewise. + (DatagramChannelImpl.innerJoin(InetAddress,NetworkInterface,InetAddress)): Likewise. + (DatagramChannelImpl.join(InetAddress,NetworkInterface)): Likewise. + (DatagramChannelImpl.join(InetAddress,NetworkInterface,InetAddress)): Likewise. + (DatagramChannelImpl.block(MembershipKeyImpl,InetAddress)): Likewise. + (DatagramChannelImpl.unblock(MembershipKeyImpl,InetAddress)): Likewise. + (DatagramChannelImpl.drop(MembershipKeyImpl)): Likewise. + (Net.getInterface4(FileDescriptor)): Likewise. + (Net.getInterface6(FileDescriptor)): Likewise. + (Net.inet4FromInt(int)): Likewise. + (Net.inet6AsByteArray(InetAddress)): Likewise. + (Net.join6(FileDescriptor,byte[],int,byte[])): Likewise. + (Net.drop6(FileDescriptor,byte[],int,byte[])): Likewise. + (Net.joinOrDrop6(boolean,FileDescriptor,byte[],int,byte[])): Likewise. + (Net.block6(FileDescriptor,byte[],int,byte[])): Likewise. + (Net.unblock6(FileDescriptor,byte[],int,byte[])): Likewise. + (Net.blockOrUnblock6(boolean,FileDescriptor,byte[],int,byte[])): Likewise. + (Net.join4(FileDescriptor,int,int,int)): Likewise. + (Net.drop4(FileDescriptor,int,int,int)): Likewise. + (Net.joinOrDrop4(boolean,FileDescriptor,int,int,int)): Likewise. + (Net.block4(FileDescriptor,int,int,int)): Likewise. + (Net.unblock4(FileDescriptor,int,int,int)): Likewise. + (Net.blockOrUnblock4(boolean,FileDescriptor,int,int,int)): Likewise. + (Net.connect(FileDescriptor,InetAddress,int)): Likewise. + (Net.connect(ProtocolFamily,FileDescriptor,InetAddress,int)): Likewise. + (Net.connect0(boolean,FileDescriptor,InetAddress,int)): Likewise. + (FileDispatcher.NO_LOCK)): Likewise. + (FileDispatcher.LOCKED)): Likewise. + (FileDispatcher.RET_EX_LOCK)): Likewise. + (FileDispatcher.INTERRUPTED)): Likewise. + (FileDispatcher.size(FileDescriptor)): Likewise. + (FileDispatcher.truncate(FileDescriptor, long)): Likewise. + (FileDispatcher.force(FileDescriptor, boolean)): Likewise. + (FileDispatcher.lock(FileDescriptor, boolean, long, long, boolean)): Likewise. + (FileDispatcher.release(FileDescriptor, long, long)): Likewise. + (FileDispatcher.force0(FileDescriptor,boolean)): Likewise. + (FileDispatcher.truncate0(FileDescriptor, long)): Likewise. + (FileDispatcher.size0(FileDescriptor)): Likewise. + (FileDispatcher.lock0(FileDescriptor, boolean, long, long, boolean)): Likewise. + (FileDispatcher.release0(FileDescriptor, long, long)): Likewise. + 2009-01-19 Andrew John Hughes <gnu_andrew@member.fsf.org> * generated/sun/nio/ch/SocketOptionRegistry.java:
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaNetGetIndexAccess.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaNetGetIndexAccess.java Tue Jan 20 00:06:18 2009 +0000 @@ -42,4 +42,5 @@ public interface JavaNetGetIndexAccess { int getIndex(NetworkInterface nf); + NetworkInterface getByIndex(int i); }
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,11 +25,11 @@ package sun.nio.ch; -import java.nio.channels.*; import java.net.SocketAddress; import java.net.InetSocketAddress; import java.io.FileDescriptor; import java.io.IOException; +import java.nio.channels.ClosedChannelException; import java.util.Set; import java.util.HashSet; import java.util.Collections;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java Tue Jan 20 00:06:18 2009 +0000 @@ -0,0 +1,224 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.nio.ch; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.io.IOException; +import java.util.HashSet; + +import org.classpath.icedtea.java.nio.channels.MembershipKey; +import org.classpath.icedtea.java.nio.channels.MulticastChannel; + +/** + * MembershipKey implementation. + */ + +class MembershipKeyImpl + extends MembershipKey +{ + private final MulticastChannel ch; + private final InetAddress group; + private final NetworkInterface interf; + private final InetAddress source; + + // true when key is valid + private volatile boolean valid = true; + + // lock used when creating or accessing blockedSet + private Object stateLock = new Object(); + + // set of source addresses that are blocked + private HashSet<InetAddress> blockedSet; + + private MembershipKeyImpl(MulticastChannel ch, + InetAddress group, + NetworkInterface interf, + InetAddress source) + { + this.ch = ch; + this.group = group; + this.interf = interf; + this.source = source; + } + + /** + * MembershipKey will additional context for IPv4 membership + */ + static class Type4 extends MembershipKeyImpl { + private final int groupAddress; + private final int interfAddress; + private final int sourceAddress; + + Type4(MulticastChannel ch, + InetAddress group, + NetworkInterface interf, + InetAddress source, + int groupAddress, + int interfAddress, + int sourceAddress) + { + super(ch, group, interf, source); + this.groupAddress = groupAddress; + this.interfAddress = interfAddress; + this.sourceAddress = sourceAddress; + } + + int groupAddress() { + return groupAddress; + } + + int interfaceAddress() { + return interfAddress; + } + + int source() { + return sourceAddress; + } + } + + /** + * MembershipKey will additional context for IPv6 membership + */ + static class Type6 extends MembershipKeyImpl { + private final byte[] groupAddress; + private final int index; + private final byte[] sourceAddress; + + Type6(MulticastChannel ch, + InetAddress group, + NetworkInterface interf, + InetAddress source, + byte[] groupAddress, + int index, + byte[] sourceAddress) + { + super(ch, group, interf, source); + this.groupAddress = groupAddress; + this.index = index; + this.sourceAddress = sourceAddress; + } + + byte[] groupAddress() { + return groupAddress; + } + + int index() { + return index; + } + + byte[] source() { + return sourceAddress; + } + } + + public boolean isValid() { + return valid; + } + + // package-private + void invalidate() { + valid = false; + } + + public void drop() throws IOException { + // delegate to channel + ((DatagramChannelImpl)ch).drop(this); + } + + + public MulticastChannel channel() { + return ch; + } + + + public InetAddress group() { + return group; + } + + + public NetworkInterface networkInterface() { + return interf; + } + + + public InetAddress sourceAddress() { + return source; + } + + + public MembershipKey block(InetAddress toBlock) + throws IOException + { + if (source != null) + throw new IllegalStateException("key is source-specific"); + + synchronized (stateLock) { + if ((blockedSet != null) && blockedSet.contains(toBlock)) { + // already blocked, nothing to do + return this; + } + + ((DatagramChannelImpl)ch).block(this, toBlock); + + // created blocked set if required and add source address + if (blockedSet == null) + blockedSet = new HashSet<InetAddress>(); + blockedSet.add(toBlock); + } + return this; + } + + + public MembershipKey unblock(InetAddress toUnblock) + throws IOException + { + synchronized (stateLock) { + if ((blockedSet == null) || !blockedSet.contains(toUnblock)) + throw new IllegalStateException("not blocked"); + + ((DatagramChannelImpl)ch).unblock(this, toUnblock); + + blockedSet.remove(toUnblock); + } + return this; + } + + + public String toString() { + StringBuilder sb = new StringBuilder(64); + sb.append('<'); + sb.append(group.getHostAddress()); + sb.append(','); + sb.append(interf.getName()); + if (source != null) { + sb.append(','); + sb.append(source.getHostAddress()); + } + sb.append('>'); + return sb.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java Tue Jan 20 00:06:18 2009 +0000 @@ -0,0 +1,132 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.nio.ch; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.*; + +import org.classpath.icedtea.java.nio.channels.MembershipKey; + +/** + * Simple registry of membership keys for a MulticastChannel. + * + * Instances of this object are not safe by multiple concurrent threads. + */ + +class MembershipRegistry { + + // map multicast group to keys + private Map<InetAddress,List<MembershipKeyImpl>> groups = null; + + MembershipRegistry() { + } + + /** + * Checks registry for membership of the group on the given + * network interface. + */ + MembershipKey checkMembership(InetAddress group, NetworkInterface interf, + InetAddress source) + { + if (groups != null) { + List<MembershipKeyImpl> keys = groups.get(group); + if (keys != null) { + for (MembershipKeyImpl key: keys) { + if (key.networkInterface().equals(interf)) { + // already a member to receive all packets so return + // existing key or detect conflict + if (source == null) { + if (key.sourceAddress() == null) + return key; + throw new IllegalStateException("Already a member to receive all packets"); + } + + // already have source-specific membership so return key + // or detect conflict + if (key.sourceAddress() == null) + throw new IllegalStateException("Already have source-specific membership"); + if (source.equals(key.sourceAddress())) + return key; + } + } + } + } + return null; + } + + /** + * Add membership to the registry, returning a new membership key. + */ + void add(MembershipKeyImpl key) { + InetAddress group = key.group(); + List<MembershipKeyImpl> keys; + if (groups == null) { + groups = new HashMap<InetAddress,List<MembershipKeyImpl>>(); + keys = null; + } else { + keys = groups.get(group); + } + if (keys == null) { + keys = new LinkedList<MembershipKeyImpl>(); + groups.put(group, keys); + } + keys.add(key); + } + + /** + * Remove a key from the registry + */ + void remove(MembershipKeyImpl key) { + InetAddress group = key.group(); + List<MembershipKeyImpl> keys = groups.get(group); + if (keys != null) { + Iterator<MembershipKeyImpl> i = keys.iterator(); + while (i.hasNext()) { + if (i.next() == key) { + i.remove(); + break; + } + } + if (keys.isEmpty()) { + groups.remove(group); + } + } + } + + /** + * Invalidate all keys in the registry + */ + void invalidateAll() { + if (groups != null) { + for (InetAddress group: groups.keySet()) { + for (MembershipKeyImpl key: groups.get(group)) { + key.invalidate(); + } + } + } + } +}
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,14 +25,22 @@ package sun.nio.ch; -import java.nio.channels.*; import java.util.concurrent.*; import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousCloseException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NonReadableChannelException; +import java.nio.channels.NonWritableChannelException; import java.security.AccessController; import java.security.PrivilegedAction; import java.io.FileDescriptor; import java.io.IOException; +import org.classpath.icedtea.java.nio.channels.AsynchronousFileChannel; +import org.classpath.icedtea.java.nio.channels.CompletionHandler; +import org.classpath.icedtea.java.nio.channels.FileLock; +import org.classpath.icedtea.java.nio.channels.ShutdownChannelGroupException; + /** * "Portable" implementation of AsynchronousFileChannel for use on operating * systems that don't support asynchronous file I/O. @@ -60,7 +68,7 @@ } // Used to make native read and write calls - private static final FileDispatcher nd = new FileDispatcherImpl(); + private static final FileDispatcher nd = new FileDispatcher(); // Thread-safe set of IDs of native threads, for signalling private final NativeThreadSet threads = new NativeThreadSet(2); @@ -209,7 +217,7 @@ throw new NonWritableChannelException(); // add to lock table - final FileLockImpl fli = addToFileLockTable(position, size, shared); + final AsynchronousFileLockImpl fli = addToFileLockTable(position, size, shared); if (fli == null) { CompletedFuture<FileLock,A> result = CompletedFuture .withFailure(this, new ClosedChannelException(), attachment); @@ -270,7 +278,7 @@ throw new NonWritableChannelException(); // add to lock table - FileLockImpl fli = addToFileLockTable(position, size, shared); + AsynchronousFileLockImpl fli = addToFileLockTable(position, size, shared); if (fli == null) throw new ClosedChannelException(); @@ -301,7 +309,7 @@ } - void release(FileLockImpl fli) throws IOException { + void release(AsynchronousFileLockImpl fli) throws IOException { try { begin(); nd.release(fdObj, fli.position(), fli.size());
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java Tue Jan 20 00:06:18 2009 +0000 @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.*; +import org.classpath.icedtea.java.nio.file.attribute.AclEntry; import org.classpath.icedtea.java.nio.file.attribute.AclFileAttributeView; import org.classpath.icedtea.java.nio.file.attribute.UserPrincipal; @@ -72,7 +73,7 @@ } - public final Map<String,?> readAttributes(String first, String[] rest) + public final Map<String,?> readAttributes(String first, String... rest) throws IOException { boolean acl = false;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java Tue Jan 20 00:06:18 2009 +0000 @@ -200,7 +200,7 @@ } - public Map<String,?> readAttributes(String first, String[] rest) + public Map<String,?> readAttributes(String first, String... rest) throws IOException { AttributesBuilder builder = AttributesBuilder.create(first, rest);
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java Tue Jan 20 00:06:18 2009 +0000 @@ -69,7 +69,7 @@ } - public final Map<String,?> readAttributes(String first, String[] rest) + public final Map<String,?> readAttributes(String first, String... rest) throws IOException { boolean total = false;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,12 +25,18 @@ package sun.nio.fs; -import java.nio.file.*; import java.security.AccessController; import java.security.PrivilegedAction; import java.io.IOException; import java.util.*; +import org.classpath.icedtea.java.nio.file.ClosedWatchServiceException; +import org.classpath.icedtea.java.nio.file.FileRef; +import org.classpath.icedtea.java.nio.file.Path; +import org.classpath.icedtea.java.nio.file.StandardWatchEventKind; +import org.classpath.icedtea.java.nio.file.WatchEvent; +import org.classpath.icedtea.java.nio.file.WatchKey; + /** * Base implementation of background poller thread used in watch service * implementations. A poller thread waits on events from the file system and
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Tue Jan 20 00:06:18 2009 +0000 @@ -27,6 +27,7 @@ import java.util.*; +import org.classpath.icedtea.java.nio.file.StandardWatchEventKind; import org.classpath.icedtea.java.nio.file.WatchEvent; import org.classpath.icedtea.java.nio.file.WatchKey;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java Tue Jan 20 00:06:18 2009 +0000 @@ -28,6 +28,9 @@ import java.util.concurrent.*; import java.io.IOException; +import org.classpath.icedtea.java.nio.file.ClosedWatchServiceException; +import org.classpath.icedtea.java.nio.file.Path; +import org.classpath.icedtea.java.nio.file.WatchEvent; import org.classpath.icedtea.java.nio.file.WatchKey; import org.classpath.icedtea.java.nio.file.WatchService;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java Tue Jan 20 00:06:18 2009 +0000 @@ -28,7 +28,11 @@ import java.util.*; import java.io.IOException; +import org.classpath.icedtea.java.nio.file.attribute.AclFileAttributeView; +import org.classpath.icedtea.java.nio.file.attribute.FileAttributeView; import org.classpath.icedtea.java.nio.file.attribute.FileOwnerAttributeView; +import org.classpath.icedtea.java.nio.file.attribute.PosixFileAttributeView; +import org.classpath.icedtea.java.nio.file.attribute.UserPrincipal; /** * An implementation of FileOwnerAttributeView that delegates to a given @@ -75,7 +79,7 @@ } - public Map<String,?> readAttributes(String first, String[] rest) throws IOException { + public Map<String,?> readAttributes(String first, String... rest) throws IOException { Map<String,Object> result = new HashMap<String,Object>(); if (first.equals("*") || first.equals(OWNER_NAME)) { result.put(OWNER_NAME, getOwner());
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,13 +25,14 @@ package sun.nio.ch; -import java.nio.channels.spi.AsynchronousChannelProvider; import java.io.IOException; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; import sun.misc.Unsafe; +import org.classpath.icedtea.java.nio.channels.spi.AsynchronousChannelProvider; + /** * AsynchronousChannelGroup implementation based on the Linux epoll facility. */
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,12 +25,17 @@ package sun.nio.ch; -import java.nio.channels.*; import java.util.concurrent.ExecutorService; import java.io.IOException; import org.classpath.icedtea.java.net.ProtocolFamily; +import org.classpath.icedtea.java.nio.channels.AsynchronousChannelGroup; +import org.classpath.icedtea.java.nio.channels.AsynchronousDatagramChannel; +import org.classpath.icedtea.java.nio.channels.AsynchronousSocketChannel; +import org.classpath.icedtea.java.nio.channels.AsynchronousServerSocketChannel; +import org.classpath.icedtea.java.nio.channels.IllegalChannelGroupException; + import org.classpath.icedtea.java.nio.channels.spi.AsynchronousChannelProvider; public class LinuxAsynchronousChannelProvider
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/Port.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/Port.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,16 +25,19 @@ package sun.nio.ch; -import java.nio.channels.spi.AsynchronousChannelProvider; -import java.nio.channels.*; import java.io.IOException; import java.io.Closeable; import java.io.FileDescriptor; +import java.nio.channels.Channel; import java.util.Map; import java.util.HashMap; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.classpath.icedtea.java.nio.channels.ShutdownChannelGroupException; + +import org.classpath.icedtea.java.nio.channels.spi.AsynchronousChannelProvider; + /** * Base implementation of AsynchronousChannelGroupImpl for Unix systems. */
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,17 +25,23 @@ package sun.nio.ch; -import java.nio.channels.*; import java.util.concurrent.*; import java.io.IOException; import java.io.FileDescriptor; import java.net.InetSocketAddress; +import java.nio.channels.AsynchronousCloseException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetBoundException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; +import org.classpath.icedtea.java.nio.channels.AcceptPendingException; +import org.classpath.icedtea.java.nio.channels.AsynchronousSocketChannel; +import org.classpath.icedtea.java.nio.channels.CompletionHandler; + /** * Unix implementation of AsynchronousServerSocketChannel */
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Mon Jan 19 14:25:02 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Tue Jan 20 00:06:18 2009 +0000 @@ -25,8 +25,11 @@ package sun.nio.ch; -import java.nio.channels.*; import java.nio.ByteBuffer; +import java.nio.channels.AlreadyConnectedException; +import java.nio.channels.AsynchronousCloseException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ConnectionPendingException; import java.net.*; import java.util.concurrent.*; import java.io.IOException; @@ -35,6 +38,10 @@ import java.security.PrivilegedAction; import sun.security.action.GetBooleanAction; +import org.classpath.icedtea.java.nio.channels.CompletionHandler; +import org.classpath.icedtea.java.nio.channels.InterruptedByTimeoutException; +import org.classpath.icedtea.java.nio.channels.ShutdownChannelGroupException; + /** * Unix implementation of AsynchronousSocketChannel */
--- a/patches/icedtea-nio2.patch Mon Jan 19 14:25:02 2009 +0000 +++ b/patches/icedtea-nio2.patch Tue Jan 20 00:06:18 2009 +0000 @@ -52,8 +52,8 @@ FILES_java = $(JAVA_JAVA_java) diff -Nru openjdk.orig/jdk/make/java/nio/FILES_java.gmk openjdk/jdk/make/java/nio/FILES_java.gmk --- openjdk.orig/jdk/make/java/nio/FILES_java.gmk 2009-01-10 03:21:38.000000000 +0000 -+++ openjdk/jdk/make/java/nio/FILES_java.gmk 2009-01-16 19:47:40.000000000 +0000 -@@ -75,7 +75,6 @@ ++++ openjdk/jdk/make/java/nio/FILES_java.gmk 2009-01-19 19:13:49.000000000 +0000 +@@ -75,12 +75,13 @@ sun/nio/ch/DefaultSelectorProvider.java \ sun/nio/ch/DirectBuffer.java \ sun/nio/ch/FileChannelImpl.java \ @@ -61,7 +61,14 @@ sun/nio/ch/FileKey.java \ sun/nio/ch/Interruptible.java \ sun/nio/ch/IOUtil.java \ -@@ -100,6 +99,7 @@ + sun/nio/ch/IOStatus.java \ + sun/nio/ch/IOVecWrapper.java \ ++ sun/nio/ch/MembershipKeyImpl.java \ ++ sun/nio/ch/MembershipRegistry.java \ + sun/nio/ch/NativeDispatcher.java \ + sun/nio/ch/NativeObject.java \ + sun/nio/ch/NativeThread.java \ +@@ -100,6 +101,7 @@ sun/nio/ch/SocketAdaptor.java \ sun/nio/ch/SocketChannelImpl.java \ sun/nio/ch/SocketDispatcher.java \ @@ -69,7 +76,7 @@ sun/nio/ch/SocketOpts.java \ sun/nio/ch/SocketOptsImpl.java \ sun/nio/ch/SourceChannelImpl.java \ -@@ -144,7 +144,150 @@ +@@ -144,7 +146,150 @@ java/lang/StringCoding.java \ \ sun/misc/Cleaner.java \ @@ -221,7 +228,7 @@ # Generated coder classes # -@@ -263,10 +406,20 @@ +@@ -263,10 +408,20 @@ \ java/nio/charset/CharacterCodingException.java \ java/nio/charset/IllegalCharsetNameException.java \ @@ -807,8 +814,8 @@ diff -Nru openjdk.orig/jdk/src/share/classes/java/net/NetworkInterface.java openjdk/jdk/src/share/classes/java/net/NetworkInterface.java --- openjdk.orig/jdk/src/share/classes/java/net/NetworkInterface.java 2009-01-16 04:07:15.000000000 +0000 -+++ openjdk/jdk/src/share/classes/java/net/NetworkInterface.java 2009-01-16 04:08:41.000000000 +0000 -@@ -529,4 +529,14 @@ ++++ openjdk/jdk/src/share/classes/java/net/NetworkInterface.java 2009-01-19 19:12:21.000000000 +0000 +@@ -529,4 +529,15 @@ } private static native void init(); @@ -818,6 +825,7 @@ + org.classpath.icedtea.misc.SharedSecrets.setJavaNetGetIndexAccess( + new org.classpath.icedtea.misc.JavaNetGetIndexAccess() { + public int getIndex(NetworkInterface nf) { return nf.getIndex(); } ++ public NetworkInterface getByIndex(int i) { return getByIndex(i); } + } + ); + } @@ -850,10 +858,59 @@ + } + } +diff -Nru openjdk.orig/jdk/src/share/classes/sun/misc/Unsafe.java openjdk/jdk/src/share/classes/sun/misc/Unsafe.java +--- openjdk.orig/jdk/src/share/classes/sun/misc/Unsafe.java 2009-01-19 15:44:19.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/misc/Unsafe.java 2009-01-19 15:47:42.000000000 +0000 +@@ -504,9 +504,33 @@ + /** + * Sets all bytes in a given block of memory to a copy of another + * block. ++ * ++ * <p>This method determines each block's base address by means of two parameters, ++ * and so it provides (in effect) a <em>double-register</em> addressing mode, ++ * as discussed in {@link #getInt(Object,long)}. When the object reference is null, ++ * the offset supplies an absolute base address. ++ * ++ * <p>The transfers are in coherent (atomic) units of a size determined ++ * by the address and length parameters. If the effective addresses and ++ * length are all even modulo 8, the transfer takes place in 'long' units. ++ * If the effective addresses and length are (resp.) even modulo 4 or 2, ++ * the transfer takes place in units of 'int' or 'short'. ++ * ++ * @since 1.7 + */ +- public native void copyMemory(long srcAddress, long destAddress, ++ public native void copyMemory(Object srcBase, long srcOffset, ++ Object destBase, long destOffset, + long bytes); ++ /** ++ * Sets all bytes in a given block of memory to a copy of another ++ * block. This provides a <em>single-register</em> addressing mode, ++ * as discussed in {@link #getInt(Object,long)}. ++ * ++ * Equivalent to <code>copyMemory(null, srcAddress, null, destAddress, bytes)</code>. ++ */ ++ public void copyMemory(long srcAddress, long destAddress, long bytes) { ++ copyMemory(null, srcAddress, null, destAddress, bytes); ++ } + + /** + * Disposes of a block of native memory, as obtained from {@link +@@ -648,6 +672,10 @@ + */ + public native int arrayBaseOffset(Class arrayClass); + ++ /** The value of {@code arrayBaseOffset(byte[].class)} */ ++ public static final int ARRAY_BYTE_BASE_OFFSET ++ = theUnsafe.arrayBaseOffset(byte[].class); ++ + /** + * Report the scale factor for addressing elements in the storage + * allocation of a given array class. However, arrays of "narrow" types diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java --- openjdk.orig/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2009-01-16 03:10:17.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2009-01-19 13:34:41.000000000 +0000 -@@ -29,10 +29,27 @@ ++++ openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2009-01-19 21:04:48.000000000 +0000 +@@ -29,10 +29,28 @@ import java.io.IOException; import java.net.*; import java.nio.ByteBuffer; @@ -876,6 +933,7 @@ +import org.classpath.icedtea.java.net.StandardSocketOption; + +import org.classpath.icedtea.java.nio.channels.DatagramChannel; ++import org.classpath.icedtea.java.nio.channels.MembershipKey; + +import org.classpath.icedtea.java.nio.channels.spi.SelectorProvider; + @@ -883,7 +941,7 @@ /** * An implementation of DatagramChannels. -@@ -53,6 +70,9 @@ +@@ -53,6 +71,9 @@ // even after the value in the file descriptor object has been set to -1 int fdVal; @@ -893,7 +951,17 @@ // IDs of native threads doing reads and writes, for signalling private volatile long readerThread = 0; private volatile long writerThread = 0; -@@ -98,15 +118,40 @@ +@@ -91,6 +112,9 @@ + // Our socket adaptor, if any + private DatagramSocket socket = null; + ++ // Multicast support ++ private MembershipRegistry registry; ++ + // -- End of fields protected by stateLock + + +@@ -98,15 +122,40 @@ throws IOException { super(sp); @@ -934,7 +1002,24 @@ this.fd = fd; this.fdVal = IOUtil.fdVal(fd); this.state = ST_UNCONNECTED; -@@ -704,4 +749,86 @@ +@@ -499,7 +548,7 @@ + } + } + +- public void bind(SocketAddress local) throws IOException { ++ public DatagramChannel bind(SocketAddress local) throws IOException { + synchronized (readLock) { + synchronized (writeLock) { + synchronized (stateLock) { +@@ -515,6 +564,7 @@ + } + } + } ++ return this; + } + + public boolean isConnected() { +@@ -704,4 +754,350 @@ initIDs(); } @@ -946,6 +1031,14 @@ + } + } + ++ public SocketAddress getLocalAddress() throws IOException { ++ synchronized (stateLock) { ++ if (!isOpen()) ++ throw new ClosedChannelException(); ++ return localAddress; ++ } ++ } ++ + public <T> DatagramChannel setOption(SocketOption<T> name, T value) + throws IOException + { @@ -999,6 +1092,61 @@ + } + } + ++ @SuppressWarnings("unchecked") ++ public <T> T getOption(SocketOption<T> name) ++ throws IOException ++ { ++ if (name == null) ++ throw new NullPointerException(); ++ if (!supportedOptions().contains(name)) ++ throw new UnsupportedOperationException("'" + name + "' not supported"); ++ ++ synchronized (stateLock) { ++ ensureOpen(); ++ ++ if (name == StandardSocketOption.IP_TOS) { ++ // IPv4 only; always return 0 on IPv6 ++ if (family == StandardProtocolFamily.INET) { ++ return (T) Net.getSocketOption(fd, family, name); ++ } else { ++ return (T) Integer.valueOf(0); ++ } ++ } ++ ++ if (name == StandardSocketOption.IP_MULTICAST_TTL || ++ name == StandardSocketOption.IP_MULTICAST_LOOP) ++ { ++ return (T) Net.getSocketOption(fd, family, name); ++ } ++ ++ if (name == StandardSocketOption.IP_MULTICAST_IF) { ++ if (family == StandardProtocolFamily.INET) { ++ int address = Net.getInterface4(fd); ++ if (address == 0) ++ return null; // default interface ++ ++ InetAddress ia = Net.inet4FromInt(address); ++ NetworkInterface ni = NetworkInterface.getByInetAddress(ia); ++ if (ni == null) ++ throw new IOException("Unable to map address to interface"); ++ return (T) ni; ++ } else { ++ int index = Net.getInterface6(fd); ++ if (index == 0) ++ return null; // default interface ++ ++ NetworkInterface ni = SharedSecrets.getJavaNetGetIndexAccess().getByIndex(index); ++ if (ni == null) ++ throw new IOException("Unable to map index to interface"); ++ return (T) ni; ++ } ++ } ++ ++ // no special handling ++ return (T) Net.getSocketOption(fd, Net.UNSPEC, name); ++ } ++ } ++ + private static class LazyInitialization { + static final Set<SocketOption<?>> defaultOptions = defaultOptions(); + @@ -1020,10 +1168,211 @@ + return LazyInitialization.defaultOptions; + } + ++ /** ++ * Joins channel's socket to the given group/interface and ++ * optional source address. ++ */ ++ private MembershipKey innerJoin(InetAddress group, ++ NetworkInterface interf, ++ InetAddress source) ++ throws IOException ++ { ++ if (!group.isMulticastAddress()) ++ throw new IllegalArgumentException("Group not a multicast address"); ++ ++ // check multicast address is compatible with this socket ++ if (!(group instanceof Inet4Address)) { ++ if (family == StandardProtocolFamily.INET) ++ throw new IllegalArgumentException("Group is not IPv4 address"); ++ if (!(group instanceof Inet6Address)) ++ throw new IllegalArgumentException("Address type not supported"); ++ } ++ ++ // check source address ++ if (source != null) { ++ if (source.isAnyLocalAddress()) ++ throw new IllegalArgumentException("Source address is a wildcard address"); ++ if (source.isMulticastAddress()) ++ throw new IllegalArgumentException("Source address is multicast address"); ++ if (source.getClass() != group.getClass()) ++ throw new IllegalArgumentException("Source address is different type to group"); ++ } ++ ++ SecurityManager sm = System.getSecurityManager(); ++ if (sm != null) ++ sm.checkMulticast(group); ++ ++ synchronized (stateLock) { ++ if (!isOpen()) ++ throw new ClosedChannelException(); ++ ++ // check the registry to see if we are already a member of the group ++ if (registry == null) { ++ registry = new MembershipRegistry(); ++ } else { ++ // return existing membership key ++ MembershipKey key = registry.checkMembership(group, interf, source); ++ if (key != null) ++ return key; ++ } ++ ++ MembershipKeyImpl key; ++ if (family == StandardProtocolFamily.INET6) { ++ int index = SharedSecrets.getJavaNetGetIndexAccess().getIndex(interf); ++ if (index == -1) ++ throw new IOException("Network interface cannot be identified"); ++ ++ // need multicast and source address as byte arrays ++ byte[] groupAddress = Net.inet6AsByteArray(group); ++ byte[] sourceAddress = (source == null) ? null : ++ Net.inet6AsByteArray(source); ++ ++ // join the group ++ int n = Net.join6(fd, groupAddress, index, sourceAddress); ++ if (n == IOStatus.UNAVAILABLE) ++ throw new UnsupportedOperationException(); ++ ++ key = new MembershipKeyImpl.Type6(this, group, interf, source, ++ groupAddress, index, sourceAddress); ++ ++ } else { ++ // need IPv4 address to identify interface ++ Inet4Address target = Net.anyInet4Address(interf); ++ if (target == null) ++ throw new IOException("Network interface not configured for IPv4"); ++ ++ int groupAddress = Net.inet4AsInt(group); ++ int targetAddress = Net.inet4AsInt(target); ++ int sourceAddress = (source == null) ? 0 : Net.inet4AsInt(source); ++ ++ // join the group ++ int n = Net.join4(fd, groupAddress, targetAddress, sourceAddress); ++ if (n == IOStatus.UNAVAILABLE) ++ throw new UnsupportedOperationException(); ++ ++ key = new MembershipKeyImpl.Type4(this, group, interf, source, ++ groupAddress, targetAddress, sourceAddress); ++ } ++ ++ registry.add(key); ++ return key; ++ } ++ } ++ ++ ++ public MembershipKey join(InetAddress group, ++ NetworkInterface interf) ++ throws IOException ++ { ++ return innerJoin(group, interf, null); ++ } ++ ++ ++ public MembershipKey join(InetAddress group, ++ NetworkInterface interf, ++ InetAddress source) ++ throws IOException ++ { ++ if (source == null) ++ throw new NullPointerException("source address is null"); ++ return innerJoin(group, interf, source); ++ } ++ ++ /** ++ * Block datagrams from given source if a memory to receive all ++ * datagrams. ++ */ ++ void block(MembershipKeyImpl key, InetAddress source) ++ throws IOException ++ { ++ assert key.channel() == this; ++ assert key.sourceAddress() == null; ++ ++ synchronized (stateLock) { ++ if (!key.isValid()) ++ throw new IllegalStateException("key is no longer valid"); ++ if (source.isAnyLocalAddress()) ++ throw new IllegalArgumentException("Source address is a wildcard address"); ++ if (source.isMulticastAddress()) ++ throw new IllegalArgumentException("Source address is multicast address"); ++ if (source.getClass() != key.group().getClass()) ++ throw new IllegalArgumentException("Source address is different type to group"); ++ ++ int n; ++ if (family == StandardProtocolFamily.INET6) { ++ MembershipKeyImpl.Type6 key6 = ++ (MembershipKeyImpl.Type6)key; ++ n = Net.block6(fd, key6.groupAddress(), key6.index(), ++ Net.inet6AsByteArray(source)); ++ } else { ++ MembershipKeyImpl.Type4 key4 = ++ (MembershipKeyImpl.Type4)key; ++ n = Net.block4(fd, key4.groupAddress(), key4.interfaceAddress(), ++ Net.inet4AsInt(source)); ++ } ++ if (n == IOStatus.UNAVAILABLE) { ++ // ancient kernel ++ throw new UnsupportedOperationException(); ++ } ++ } ++ } ++ ++ /** ++ * Unblock given source. ++ */ ++ void unblock(MembershipKeyImpl key, InetAddress source) ++ throws IOException ++ { ++ assert key.channel() == this; ++ assert key.sourceAddress() == null; ++ ++ synchronized (stateLock) { ++ if (!key.isValid()) ++ throw new IllegalStateException("key is no longer valid"); ++ ++ if (family == StandardProtocolFamily.INET6) { ++ MembershipKeyImpl.Type6 key6 = ++ (MembershipKeyImpl.Type6)key; ++ Net.unblock6(fd, key6.groupAddress(), key6.index(), ++ Net.inet6AsByteArray(source)); ++ } else { ++ MembershipKeyImpl.Type4 key4 = ++ (MembershipKeyImpl.Type4)key; ++ Net.unblock4(fd, key4.groupAddress(), key4.interfaceAddress(), ++ Net.inet4AsInt(source)); ++ } ++ } ++ } ++ ++ // package-private ++ void drop(MembershipKeyImpl key) ++ throws IOException ++ { ++ assert key.channel() == this; ++ ++ synchronized (stateLock) { ++ if (!key.isValid()) ++ return; ++ ++ if (family == StandardProtocolFamily.INET6) { ++ MembershipKeyImpl.Type6 key6 = ++ (MembershipKeyImpl.Type6)key; ++ Net.drop6(fd, key6.groupAddress(), key6.index(), key6.source()); ++ } else { ++ MembershipKeyImpl.Type4 key4 = (MembershipKeyImpl.Type4)key; ++ Net.drop4(fd, key4.groupAddress(), key4.interfaceAddress(), ++ key4.source()); ++ } ++ ++ key.invalidate(); ++ registry.remove(key); ++ } ++ } ++ } diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/Net.java openjdk/jdk/src/share/classes/sun/nio/ch/Net.java --- openjdk.orig/jdk/src/share/classes/sun/nio/ch/Net.java 2009-01-15 17:37:33.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/nio/ch/Net.java 2009-01-19 13:37:55.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/nio/ch/Net.java 2009-01-19 23:21:37.000000000 +0000 @@ -30,6 +30,15 @@ import java.net.*; import java.nio.channels.*; @@ -1068,7 +1417,7 @@ static native void bind(FileDescriptor fd, InetAddress addr, int port) throws IOException; -@@ -179,4 +196,164 @@ +@@ -179,4 +196,314 @@ initIDs(); } @@ -1182,6 +1531,10 @@ + + static native void setInterface4(FileDescriptor fd, int interf) throws IOException; + ++ static native int getInterface4(FileDescriptor fd) throws IOException; ++ ++ static native int getInterface6(FileDescriptor fd) throws IOException; ++ + /** + * Returns any IPv4 address of the given network interface, or + * null if the interface does not have any IPv4 addresses. @@ -1216,6 +1569,47 @@ + throw new AssertionError("Should not reach here"); + } + ++ /** ++ * Returns an InetAddress from the given IPv4 address ++ * represented as an int. ++ */ ++ static InetAddress inet4FromInt(int address) { ++ byte[] addr = new byte[4]; ++ addr[0] = (byte) ((address >>> 24) & 0xFF); ++ addr[1] = (byte) ((address >>> 16) & 0xFF); ++ addr[2] = (byte) ((address >>> 8) & 0xFF); ++ addr[3] = (byte) (address & 0xFF); ++ try { ++ return InetAddress.getByAddress(addr); ++ } catch (UnknownHostException uhe) { ++ throw new AssertionError("Should not reach here"); ++ } ++ } ++ ++ /** ++ * Returns an IPv6 address as a byte array ++ */ ++ static byte[] inet6AsByteArray(InetAddress ia) { ++ if (ia instanceof Inet6Address) { ++ return ia.getAddress(); ++ } ++ ++ // need to construct IPv4-mapped address ++ if (ia instanceof Inet4Address) { ++ byte[] ip4address = ia.getAddress(); ++ byte[] address = new byte[16]; ++ address[10] = (byte)0xff; ++ address[11] = (byte)0xff; ++ address[12] = ip4address[0]; ++ address[13] = ip4address[1]; ++ address[14] = ip4address[2]; ++ address[15] = ip4address[3]; ++ return address; ++ } ++ ++ throw new AssertionError("Should not reach here"); ++ } ++ + // -- Miscellaneous utilities -- + + private static volatile boolean checkedIPv6 = false; @@ -1232,6 +1626,111 @@ + return isIPv6Available; + } + ++ /** ++ * Join IPv6 multicast group ++ */ ++ static int join6(FileDescriptor fd, byte[] group, int index, byte[] source) ++ throws IOException ++ { ++ return joinOrDrop6(true, fd, group, index, source); ++ } ++ ++ /** ++ * Drop membership of IPv6 multicast group ++ */ ++ static void drop6(FileDescriptor fd, byte[] group, int index, byte[] source) ++ throws IOException ++ { ++ joinOrDrop6(false, fd, group, index, source); ++ } ++ ++ private static native int joinOrDrop6(boolean join, FileDescriptor fd, byte[] group, int index, byte[] source) ++ throws IOException; ++ ++ /** ++ * Block IPv6 source ++ */ ++ static int block6(FileDescriptor fd, byte[] group, int index, byte[] source) ++ throws IOException ++ { ++ return blockOrUnblock6(true, fd, group, index, source); ++ } ++ ++ /** ++ * Unblock IPv6 source ++ */ ++ static void unblock6(FileDescriptor fd, byte[] group, int index, byte[] source) ++ throws IOException ++ { ++ blockOrUnblock6(false, fd, group, index, source); ++ } ++ ++ static native int blockOrUnblock6(boolean block, FileDescriptor fd, byte[] group, int index, byte[] source) ++ throws IOException; ++ ++ /** ++ * Join IPv4 multicast group ++ */ ++ static int join4(FileDescriptor fd, int group, int interf, int source) ++ throws IOException ++ { ++ return joinOrDrop4(true, fd, group, interf, source); ++ } ++ ++ /** ++ * Drop membership of IPv4 multicast group ++ */ ++ static void drop4(FileDescriptor fd, int group, int interf, int source) ++ throws IOException ++ { ++ joinOrDrop4(false, fd, group, interf, source); ++ } ++ ++ private static native int joinOrDrop4(boolean join, FileDescriptor fd, int group, int interf, int source) ++ throws IOException; ++ ++ /** ++ * Block IPv4 source ++ */ ++ static int block4(FileDescriptor fd, int group, int interf, int source) ++ throws IOException ++ { ++ return blockOrUnblock4(true, fd, group, interf, source); ++ } ++ ++ /** ++ * Unblock IPv4 source ++ */ ++ static void unblock4(FileDescriptor fd, int group, int interf, int source) ++ throws IOException ++ { ++ blockOrUnblock4(false, fd, group, interf, source); ++ } ++ ++ private static native int blockOrUnblock4(boolean block, FileDescriptor fd, int group, ++ int interf, int source) ++ throws IOException; ++ ++ static int connect(FileDescriptor fd, InetAddress remote, int remotePort) ++ throws IOException ++ { ++ return connect(UNSPEC, fd, remote, remotePort); ++ } ++ ++ static int connect(ProtocolFamily family, FileDescriptor fd, InetAddress remote, int remotePort) ++ throws IOException ++ { ++ boolean preferIPv6 = isIPv6Available() && ++ (family != StandardProtocolFamily.INET); ++ return connect0(preferIPv6, fd, remote, remotePort); ++ } ++ ++ private static native int connect0(boolean preferIPv6, ++ FileDescriptor fd, ++ InetAddress remote, ++ int remotePort) ++ throws IOException; ++ } diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java openjdk/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java --- openjdk.orig/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java 2009-01-16 03:01:03.000000000 +0000 @@ -1292,6 +1791,69 @@ public static final String SOCKET_RESOLVE_ACTION = "resolve"; public static final String SOCKET_CONNECT_ACTION = "connect"; +diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java openjdk/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java +--- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java 2009-01-19 22:33:37.000000000 +0000 ++++ openjdk/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java 2009-01-19 22:33:01.000000000 +0000 +@@ -35,6 +35,11 @@ + class FileDispatcher extends NativeDispatcher + { + ++ public static final int NO_LOCK = -1; // Failed to lock ++ public static final int LOCKED = 0; // Obtained requested lock ++ public static final int RET_EX_LOCK = 1; // Obtained exclusive lock ++ public static final int INTERRUPTED = 2; // Request interrupted ++ + static { + Util.load(); + init(); +@@ -77,6 +82,28 @@ + preClose0(fd); + } + ++ long size(FileDescriptor fd) throws IOException { ++ return size0(fd); ++ } ++ ++ int truncate(FileDescriptor fd, long size) throws IOException { ++ return truncate0(fd, size); ++ } ++ ++ int force(FileDescriptor fd, boolean metaData) throws IOException { ++ return force0(fd, metaData); ++ } ++ ++ int lock(FileDescriptor fd, boolean blocking, long pos, long size, ++ boolean shared) throws IOException ++ { ++ return lock0(fd, blocking, pos, size, shared); ++ } ++ ++ void release(FileDescriptor fd, long pos, long size) throws IOException { ++ release0(fd, pos, size); ++ } ++ + // -- Native methods -- + + static native int read0(FileDescriptor fd, long address, int len) +@@ -105,4 +132,18 @@ + + static native void init(); + ++ static native int force0(FileDescriptor fd, boolean metaData) ++ throws IOException; ++ ++ static native int truncate0(FileDescriptor fd, long size) ++ throws IOException; ++ ++ static native long size0(FileDescriptor fd) throws IOException; ++ ++ static native int lock0(FileDescriptor fd, boolean blocking, long pos, ++ long size, boolean shared) throws IOException; ++ ++ static native void release0(FileDescriptor fd, long pos, long size) ++ throws IOException; ++ + } diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java openjdk/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java --- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java 2009-01-19 13:29:01.000000000 +0000 +++ openjdk/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java 2009-01-19 13:29:27.000000000 +0000 @@ -1305,3 +1867,65 @@ class InheritedChannel { +diff -Nru openjdk.orig/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java openjdk/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java +--- openjdk.orig/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java 2009-01-19 22:35:32.000000000 +0000 ++++ openjdk/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java 2009-01-19 22:37:37.000000000 +0000 +@@ -36,6 +36,11 @@ + class FileDispatcher extends NativeDispatcher + { + ++ public static final int NO_LOCK = -1; // Failed to lock ++ public static final int LOCKED = 0; // Obtained requested lock ++ public static final int RET_EX_LOCK = 1; // Obtained exclusive lock ++ public static final int INTERRUPTED = 2; // Request interrupted ++ + static { + Util.load(); + } +@@ -78,6 +83,28 @@ + close0(fd); + } + ++ int force(FileDescriptor fd, boolean metaData) throws IOException { ++ return force0(fd, metaData); ++ } ++ ++ int truncate(FileDescriptor fd, long size) throws IOException { ++ return truncate0(fd, size); ++ } ++ ++ long size(FileDescriptor fd) throws IOException { ++ return size0(fd); ++ } ++ ++ int lock(FileDescriptor fd, boolean blocking, long pos, long size, ++ boolean shared) throws IOException ++ { ++ return lock0(fd, blocking, pos, size, shared); ++ } ++ ++ void release(FileDescriptor fd, long pos, long size) throws IOException { ++ release0(fd, pos, size); ++ } ++ + //-- Native methods + + static native int read0(FileDescriptor fd, long address, int len) +@@ -102,4 +129,17 @@ + + static native void closeByHandle(long fd) throws IOException; + ++ static native int force0(FileDescriptor fd, boolean metaData) ++ throws IOException; ++ ++ static native int truncate0(FileDescriptor fd, long size) ++ throws IOException; ++ ++ static native long size0(FileDescriptor fd) throws IOException; ++ ++ static native int lock0(FileDescriptor fd, boolean blocking, long pos, ++ long size, boolean shared) throws IOException; ++ ++ static native void release0(FileDescriptor fd, long pos, long size) ++ throws IOException; + }