6915313: Reorganize implementation to make it more feasible to port to JDK6
Summary: This makes the SCTP implementation easier to run with Suns JDK6.
Reviewed-by: alanb
--- a/jdk/make/com/sun/nio/sctp/FILES_java.gmk Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/make/com/sun/nio/sctp/FILES_java.gmk Mon Jan 11 16:04:05 2010 +0000
@@ -57,8 +57,7 @@
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 \
--- a/jdk/make/com/sun/nio/sctp/mapfile-vers Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/make/com/sun/nio/sctp/mapfile-vers Mon Jan 11 16:04:05 2010 +0000
@@ -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;
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java Mon Jan 11 16:04:05 2010 +0000
@@ -38,7 +38,6 @@
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.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 @@
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 @@
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 @@
if (add) {
for (InetSocketAddress addr : localAddresses) {
if (addr.getAddress().equals(address)) {
- throw new AlreadyBoundException();
+ SctpNet.throwAlreadyBoundException();
}
}
} else { /*removing */
@@ -370,7 +365,7 @@
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 @@
@Override
public void implCloseSelectableChannel() throws IOException {
synchronized (stateLock) {
- nd.preClose(fd);
+ SctpNet.preClose(fdVal);
if (receiverThread != 0)
NativeThread.signal(receiverThread);
@@ -662,7 +657,7 @@
/* 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 @@
java.security.AccessController.doPrivileged(
new sun.security.action.LoadLibraryAction("sctp"));
initIDs();
- nd = new SctpSocketDispatcher();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java Mon Jan 11 16:04:05 2010 +0000
@@ -38,7 +38,6 @@
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 @@
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 @@
synchronized (stateLock) {
ensureOpen();
if (isBound())
- throw new AlreadyBoundException();
+ SctpNet.throwAlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
@@ -155,7 +151,7 @@
if (isa.getAddress().isAnyLocalAddress())
wildcard = true;
- Net.listen(fd, backlog < 1 ? 50 : backlog);
+ SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog);
}
}
}
@@ -196,7 +192,7 @@
if (add) {
for (InetSocketAddress addr : localAddresses) {
if (addr.getAddress().equals(address)) {
- throw new AlreadyBoundException();
+ SctpNet.throwAlreadyBoundException();
}
}
} else { /*removing */
@@ -284,7 +280,7 @@
@Override
public void implCloseSelectableChannel() throws IOException {
synchronized (stateLock) {
- nd.preClose(fd);
+ SctpNet.preClose(fdVal);
if (receiverThread != 0)
NativeThread.signal(receiverThread);
@@ -375,7 +371,7 @@
/* 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 @@
Util.load(); /* loads nio & net native libraries */
java.security.AccessController.doPrivileged(
new sun.security.action.LoadLibraryAction("sctp"));
- nd = new SctpSocketDispatcher();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java Mon Jan 11 16:04:05 2010 +0000
@@ -29,6 +29,7 @@
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 @@
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 @@
/* 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 @@
throws IOException;
static native void shutdown0(int fd, int assocId);
+
+ static native void init();
+
+ static {
+ init();
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java Mon Jan 11 16:04:05 2010 +0000
@@ -33,7 +33,6 @@
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 @@
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 @@
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 @@
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 @@
if (add) {
for (InetSocketAddress addr : localAddresses) {
if (addr.getAddress().equals(address)) {
- throw new AlreadyBoundException();
+ SctpNet.throwAlreadyBoundException();
}
}
} else { /*removing */
@@ -261,7 +257,7 @@
@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 @@
// 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 @@
Util.load(); // loads nio & net native libraries
java.security.AccessController.doPrivileged(
new sun.security.action.LoadLibraryAction("sctp"));
- nd = new SctpSocketDispatcher();
initIDs();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpSocketDispatcher.java Sun Jan 10 12:29:19 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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);
- }
-}
--- a/jdk/src/solaris/native/sun/nio/ch/SctpNet.c Sun Jan 10 12:29:19 2010 +0000
+++ b/jdk/src/solaris/native/sun/nio/ch/SctpNet.c Mon Jan 11 16:04:05 2010 +0000
@@ -48,6 +48,9 @@
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.
@@ -109,6 +112,23 @@
/*
* 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
* Signature: (Z)I
*/
@@ -184,6 +204,76 @@
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) {