6915313: Reorganize implementation to make it more feasible to port to JDK6
This makes the SCTP implementation easier to run with Suns JDK6. Reviewed-by: alanb
This commit is contained in:
parent
30d2fd5f41
commit
1d92211cb6
@ -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 \
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user