diff --git a/jdk/make/com/sun/nio/sctp/FILES_java.gmk b/jdk/make/com/sun/nio/sctp/FILES_java.gmk index 8be820fae9c..09c1563dcb9 100644 --- a/jdk/make/com/sun/nio/sctp/FILES_java.gmk +++ b/jdk/make/com/sun/nio/sctp/FILES_java.gmk @@ -57,8 +57,7 @@ FILES_java += \ sun/nio/ch/SctpResultContainer.java \ sun/nio/ch/SctpSendFailed.java \ sun/nio/ch/SctpServerChannelImpl.java \ - sun/nio/ch/SctpShutdown.java \ - sun/nio/ch/SctpSocketDispatcher.java + sun/nio/ch/SctpShutdown.java else FILES_java += \ sun/nio/ch/SctpChannelImpl.java \ diff --git a/jdk/make/com/sun/nio/sctp/mapfile-vers b/jdk/make/com/sun/nio/sctp/mapfile-vers index 0e5138586a0..21ac26ea7d8 100644 --- a/jdk/make/com/sun/nio/sctp/mapfile-vers +++ b/jdk/make/com/sun/nio/sctp/mapfile-vers @@ -25,9 +25,14 @@ SUNWprivate_1.1 { global: + Java_sun_nio_ch_SctpNet_init; Java_sun_nio_ch_SctpNet_socket0; Java_sun_nio_ch_SctpNet_bindx; Java_sun_nio_ch_SctpNet_branch0; + Java_sun_nio_ch_SctpNet_listen0; + Java_sun_nio_ch_SctpNet_connect0; + Java_sun_nio_ch_SctpNet_close0; + Java_sun_nio_ch_SctpNet_preClose0; Java_sun_nio_ch_SctpNet_getLocalAddresses0; Java_sun_nio_ch_SctpNet_getRemoteAddresses0; Java_sun_nio_ch_SctpNet_getPrimAddrOption0; diff --git a/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java index d7842570a2c..be64c9c0a68 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java @@ -38,7 +38,6 @@ import java.nio.channels.SelectionKey; import java.nio.channels.ClosedChannelException; import java.nio.channels.ConnectionPendingException; import java.nio.channels.NoConnectionPendingException; -import java.nio.channels.AlreadyBoundException; import java.nio.channels.AlreadyConnectedException; import java.nio.channels.NotYetBoundException; import java.nio.channels.NotYetConnectedException; @@ -54,7 +53,6 @@ import com.sun.nio.sctp.MessageInfo; import com.sun.nio.sctp.NotificationHandler; import com.sun.nio.sctp.SctpChannel; import com.sun.nio.sctp.SctpSocketOption; -import sun.nio.ch.NativeDispatcher; import sun.nio.ch.PollArrayWrapper; import sun.nio.ch.SelChImpl; import static com.sun.nio.sctp.SctpStandardSocketOption.*; @@ -69,9 +67,6 @@ import static sun.nio.ch.SctpResultContainer.SHUTDOWN; public class SctpChannelImpl extends SctpChannel implements SelChImpl { - /* Used to make native close and preClose calls */ - private static NativeDispatcher nd; - private final FileDescriptor fd; private final int fdVal; @@ -182,7 +177,7 @@ public class SctpChannelImpl extends SctpChannel synchronized (stateLock) { ensureOpenAndUnconnected(); if (isBound()) - throw new AlreadyBoundException(); + SctpNet.throwAlreadyBoundException(); InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); Net.bind(fd, isa.getAddress(), isa.getPort()); @@ -234,7 +229,7 @@ public class SctpChannelImpl extends SctpChannel if (add) { for (InetSocketAddress addr : localAddresses) { if (addr.getAddress().equals(address)) { - throw new AlreadyBoundException(); + SctpNet.throwAlreadyBoundException(); } } } else { /*removing */ @@ -370,7 +365,7 @@ public class SctpChannelImpl extends SctpChannel InetAddress ia = isa.getAddress(); if (ia.isAnyLocalAddress()) ia = InetAddress.getLocalHost(); - n = Net.connect(fd, ia, isa.getPort()); + n = SctpNet.connect(fdVal, ia, isa.getPort()); if ( (n == IOStatus.INTERRUPTED) && isOpen()) continue; @@ -556,7 +551,7 @@ public class SctpChannelImpl extends SctpChannel @Override public void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { - nd.preClose(fd); + SctpNet.preClose(fdVal); if (receiverThread != 0) NativeThread.signal(receiverThread); @@ -662,7 +657,7 @@ public class SctpChannelImpl extends SctpChannel /* Postpone the kill if there is a waiting reader * or writer thread. */ if (receiverThread == 0 && senderThread == 0) { - nd.close(fd); + SctpNet.close(fdVal); state = ChannelState.KILLED; } else { state = ChannelState.KILLPENDING; @@ -1097,6 +1092,5 @@ public class SctpChannelImpl extends SctpChannel java.security.AccessController.doPrivileged( new sun.security.action.LoadLibraryAction("sctp")); initIDs(); - nd = new SctpSocketDispatcher(); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java index b8457fdba27..92ebb3f67b5 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java @@ -38,7 +38,6 @@ import java.util.HashSet; import java.util.HashMap; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; -import java.nio.channels.AlreadyBoundException; import java.nio.channels.ClosedChannelException; import java.nio.channels.NotYetBoundException; import java.nio.channels.spi.SelectorProvider; @@ -63,9 +62,6 @@ import static sun.nio.ch.SctpResultContainer.*; public class SctpMultiChannelImpl extends SctpMultiChannel implements SelChImpl { - /* Used to make native close and preClose calls */ - private static NativeDispatcher nd; - private final FileDescriptor fd; private final int fdVal; @@ -140,7 +136,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel synchronized (stateLock) { ensureOpen(); if (isBound()) - throw new AlreadyBoundException(); + SctpNet.throwAlreadyBoundException(); InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); @@ -155,7 +151,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel if (isa.getAddress().isAnyLocalAddress()) wildcard = true; - Net.listen(fd, backlog < 1 ? 50 : backlog); + SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog); } } } @@ -196,7 +192,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel if (add) { for (InetSocketAddress addr : localAddresses) { if (addr.getAddress().equals(address)) { - throw new AlreadyBoundException(); + SctpNet.throwAlreadyBoundException(); } } } else { /*removing */ @@ -284,7 +280,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel @Override public void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { - nd.preClose(fd); + SctpNet.preClose(fdVal); if (receiverThread != 0) NativeThread.signal(receiverThread); @@ -375,7 +371,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel /* Postpone the kill if there is a thread sending or receiving. */ if (receiverThread == 0 && senderThread == 0) { - nd.close(fd); + SctpNet.close(fdVal); state = ChannelState.KILLED; } else { state = ChannelState.KILLPENDING; @@ -981,6 +977,5 @@ public class SctpMultiChannelImpl extends SctpMultiChannel Util.load(); /* loads nio & net native libraries */ java.security.AccessController.doPrivileged( new sun.security.action.LoadLibraryAction("sctp")); - nd = new SctpSocketDispatcher(); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java b/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java index f4cd5005f15..39019e7fd0a 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java +++ b/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.nio.channels.AlreadyBoundException; import java.util.Set; import java.util.HashSet; import java.security.AccessController; @@ -52,8 +53,29 @@ public class SctpNet { return false; } + static boolean throwAlreadyBoundException() throws IOException { + throw new AlreadyBoundException(); + } + + static void listen(int fd, int backlog) throws IOException { + listen0(fd, backlog); + } + + static int connect(int fd, InetAddress remote, int remotePort) + throws IOException { + return connect0(fd, remote, remotePort); + } + + static void close(int fd) throws IOException { + close0(fd); + } + + static void preClose(int fd) throws IOException { + preClose0(fd); + } + /** - * @param oneToone + * @param oneToOne * if {@code true} returns a one-to-one sctp socket, otherwise * returns a one-to-many sctp socket */ @@ -240,6 +262,15 @@ public class SctpNet { /* Native Methods */ static native int socket0(boolean oneToOne) throws IOException; + static native void listen0(int fd, int backlog) throws IOException; + + static native int connect0(int fd, InetAddress remote, int remotePort) + throws IOException; + + static native void close0(int fd) throws IOException; + + static native void preClose0(int fd) throws IOException; + static native void bindx(int fd, InetAddress[] addrs, int port, int length, boolean add, boolean preferIPv6) throws IOException; @@ -271,5 +302,11 @@ public class SctpNet { throws IOException; static native void shutdown0(int fd, int assocId); + + static native void init(); + + static { + init(); + } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java index 5381591b7f0..740905a0941 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java @@ -33,7 +33,6 @@ import java.util.Collections; import java.util.Set; import java.util.HashSet; import java.nio.channels.SelectionKey; -import java.nio.channels.AlreadyBoundException; import java.nio.channels.ClosedChannelException; import java.nio.channels.NotYetBoundException; import java.nio.channels.spi.SelectorProvider; @@ -49,9 +48,6 @@ import com.sun.nio.sctp.SctpStandardSocketOption; public class SctpServerChannelImpl extends SctpServerChannel implements SelChImpl { - /* Used to make native close and preClose calls */ - private static NativeDispatcher nd; - private final FileDescriptor fd; private final int fdVal; @@ -103,7 +99,7 @@ public class SctpServerChannelImpl extends SctpServerChannel if (!isOpen()) throw new ClosedChannelException(); if (isBound()) - throw new AlreadyBoundException(); + SctpNet.throwAlreadyBoundException(); InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); @@ -118,7 +114,7 @@ public class SctpServerChannelImpl extends SctpServerChannel if (isa.getAddress().isAnyLocalAddress()) wildcard = true; - Net.listen(fd, backlog < 1 ? 50 : backlog); + SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog); } } return this; @@ -156,7 +152,7 @@ public class SctpServerChannelImpl extends SctpServerChannel if (add) { for (InetSocketAddress addr : localAddresses) { if (addr.getAddress().equals(address)) { - throw new AlreadyBoundException(); + SctpNet.throwAlreadyBoundException(); } } } else { /*removing */ @@ -261,7 +257,7 @@ public class SctpServerChannelImpl extends SctpServerChannel @Override public void implCloseSelectableChannel() throws IOException { synchronized (stateLock) { - nd.preClose(fd); + SctpNet.preClose(fdVal); if (thread != 0) NativeThread.signal(thread); if (!isRegistered()) @@ -282,7 +278,7 @@ public class SctpServerChannelImpl extends SctpServerChannel // Postpone the kill if there is a thread in accept if (thread == 0) { - nd.close(fd); + SctpNet.close(fdVal); state = ChannelState.KILLED; } else { state = ChannelState.KILLPENDING; @@ -423,7 +419,6 @@ public class SctpServerChannelImpl extends SctpServerChannel Util.load(); // loads nio & net native libraries java.security.AccessController.doPrivileged( new sun.security.action.LoadLibraryAction("sctp")); - nd = new SctpSocketDispatcher(); initIDs(); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/SctpSocketDispatcher.java b/jdk/src/solaris/classes/sun/nio/ch/SctpSocketDispatcher.java deleted file mode 100644 index 937a7392496..00000000000 --- a/jdk/src/solaris/classes/sun/nio/ch/SctpSocketDispatcher.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2009 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.io.IOException; -import java.io.FileDescriptor; - -/** - * Only used for {@code close} and {@code preclose}. All other methods - * throw {@code IOException}. - */ -class SctpSocketDispatcher extends NativeDispatcher { - @Override - @SuppressWarnings("unused") - int read(FileDescriptor fd, long address, int len) throws IOException { - throw new IOException("Operation Unsupported"); - } - - @Override - @SuppressWarnings("unused") - long readv(FileDescriptor fd, long address, int len) throws IOException { - throw new IOException("Operation Unsupported"); - } - - @Override - @SuppressWarnings("unused") - int write(FileDescriptor fd, long address, int len) throws IOException { - throw new IOException("Operation Unsupported"); - } - - @Override - @SuppressWarnings("unused") - long writev(FileDescriptor fd, long address, int len) throws IOException { - throw new IOException("Operation Unsupported"); - } - - @Override - void close(FileDescriptor fd) throws IOException { - FileDispatcherImpl.close0(fd); - } - - @Override - void preClose(FileDescriptor fd) throws IOException { - FileDispatcherImpl.preClose0(fd); - } -} diff --git a/jdk/src/solaris/native/sun/nio/ch/SctpNet.c b/jdk/src/solaris/native/sun/nio/ch/SctpNet.c index 85611bd0d9d..8a27807c599 100644 --- a/jdk/src/solaris/native/sun/nio/ch/SctpNet.c +++ b/jdk/src/solaris/native/sun/nio/ch/SctpNet.c @@ -48,6 +48,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad return JNI_VERSION_1_2; } +static int preCloseFD = -1; /* File descriptor to which we dup other fd's + before closing them for real */ + /** * Loads the native sctp library that contains the socket extension * functions, as well as locating the individual functions. @@ -107,6 +110,23 @@ jboolean loadSocketExtensionFuncs return JNI_TRUE; } +/* + * Class: sun_nio_ch_SctpNet + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_sun_nio_ch_SctpNet_init + (JNIEnv *env, jclass cl) { + int sp[2]; + if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) { + JNU_ThrowIOExceptionWithLastError(env, "socketpair failed"); + return; + } + preCloseFD = sp[0]; + close(sp[1]); +} + /* * Class: sun_nio_ch_SctpNet * Method: socket0 @@ -184,6 +204,76 @@ JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_bindx free(sap); } +/* + * Class: sun_nio_ch_SctpNet + * Method: listen0 + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_sun_nio_ch_SctpNet_listen0 + (JNIEnv *env, jclass cl, jint fd, jint backlog) { + if (listen(fd, backlog) < 0) + handleSocketError(env, errno); +} + +/* + * Class: sun_nio_ch_SctpNet + * Method: connect0 + * Signature: (ILjava/net/InetAddress;I)I + */ +JNIEXPORT jint JNICALL +Java_sun_nio_ch_SctpNet_connect0 + (JNIEnv *env, jclass clazz, int fd, jobject iao, jint port) { + SOCKADDR sa; + int sa_len = SOCKADDR_LEN; + int rv; + + if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *) &sa, + &sa_len, JNI_TRUE) != 0) { + return IOS_THROWN; + } + + rv = connect(fd, (struct sockaddr *)&sa, sa_len); + if (rv != 0) { + if (errno == EINPROGRESS) { + return IOS_UNAVAILABLE; + } else if (errno == EINTR) { + return IOS_INTERRUPTED; + } + return handleSocketError(env, errno); + } + return 1; +} + +/* + * Class: sun_nio_ch_SctpNet + * Method: close0 + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_sun_nio_ch_SctpNet_close0 + (JNIEnv *env, jclass clazz, jint fd) { + if (fd != -1) { + int rv = close(fd); + if (rv < 0) + JNU_ThrowIOExceptionWithLastError(env, "Close failed"); + } +} + +/* + * Class: sun_nio_ch_SctpNet + * Method: preClose0 + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_sun_nio_ch_SctpNet_preClose0 + (JNIEnv *env, jclass clazz, jint fd) { + if (preCloseFD >= 0) { + if (dup2(preCloseFD, fd) < 0) + JNU_ThrowIOExceptionWithLastError(env, "dup2 failed"); + } +} + void initializeISA (JNIEnv* env) { if (isaCls == 0) {