OpenJDK / portola / portola
changeset 7971:ca5a32210b1b
7002957: (fc) FileChannel.transferTo fails to load libsendfile on Solaris 64-bit
Reviewed-by: chegar
author | alanb |
---|---|
date | Mon, 10 Jan 2011 09:32:32 +0000 |
parents | af1579474d16 |
children | 1d0e051daa24 |
files | jdk/make/java/nio/Makefile jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c |
diffstat | 2 files changed, 35 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/make/java/nio/Makefile Fri Jan 07 15:39:58 2011 -0800 +++ b/jdk/make/java/nio/Makefile Mon Jan 10 09:32:32 2011 +0000 @@ -296,7 +296,7 @@ OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -lnet -lpthread -ldl endif ifeq ($(PLATFORM), solaris) -OTHER_LDLIBS += $(JVMLIB) $(LIBSOCKET) -lposix4 -ldl \ +OTHER_LDLIBS += $(JVMLIB) $(LIBSOCKET) -lposix4 -ldl -lsendfile \ -L$(LIBDIR)/$(LIBARCH) -ljava -lnet endif # PLATFORM
--- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c Fri Jan 07 15:39:58 2011 -0800 +++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c Mon Jan 10 09:32:32 2011 +0000 @@ -35,48 +35,17 @@ #include "nio_util.h" #include <dlfcn.h> -static jfieldID chan_fd; /* jobject 'fd' in sun.io.FileChannelImpl */ - -#ifdef __solaris__ -typedef struct sendfilevec64 { - int sfv_fd; /* input fd */ - uint_t sfv_flag; /* Flags. see below */ - off64_t sfv_off; /* offset to start reading from */ - size_t sfv_len; /* amount of data */ -} sendfilevec_t; - -/* Function pointer for sendfilev on Solaris 8+ */ -typedef ssize_t sendfile_func(int fildes, const struct sendfilevec64 *vec, - int sfvcnt, size_t *xferred); - -sendfile_func* my_sendfile_func = NULL; +#if defined(__linux__) || defined(__solaris__) +#include <sys/sendfile.h> #endif -#ifdef __linux__ -#include <sys/sendfile.h> - -/* Function pointer for sendfile64 on Linux 2.6 (and newer 2.4 kernels) */ -typedef ssize_t sendfile64_func(int out_fd, int in_fd, off64_t *offset, size_t count); - -sendfile64_func* my_sendfile64_func = NULL; -#endif +static jfieldID chan_fd; /* jobject 'fd' in sun.io.FileChannelImpl */ JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz) { jlong pageSize = sysconf(_SC_PAGESIZE); chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;"); - -#ifdef __solaris__ - if (dlopen("/usr/lib/libsendfile.so.1", RTLD_GLOBAL | RTLD_LAZY) != NULL) { - my_sendfile_func = (sendfile_func*) dlsym(RTLD_DEFAULT, "sendfilev64"); - } -#endif - -#ifdef __linux__ - my_sendfile64_func = (sendfile64_func*) dlsym(RTLD_DEFAULT, "sendfile64"); -#endif - return pageSize; } @@ -178,22 +147,9 @@ jlong position, jlong count, jint dstFD) { -#ifdef __linux__ - jlong max = (jlong)java_lang_Integer_MAX_VALUE; - jlong n; - - if (my_sendfile64_func == NULL) { - off_t offset; - if (position > max) - return IOS_UNSUPPORTED_CASE; - if (count > max) - count = max; - offset = (off_t)position; - n = sendfile(dstFD, srcFD, &offset, (size_t)count); - } else { - off64_t offset = (off64_t)position; - n = (*my_sendfile64_func)(dstFD, srcFD, &offset, (size_t)count); - } +#if defined(__linux__) + off64_t offset = (off64_t)position; + jlong n = sendfile64(dstFD, srcFD, &offset, (size_t)count); if (n < 0) { if (errno == EAGAIN) return IOS_UNAVAILABLE; @@ -206,41 +162,37 @@ return IOS_THROWN; } return n; -#endif +#elif defined (__solaris__) + sendfilevec64_t sfv; + size_t numBytes = 0; + jlong result; -#ifdef __solaris__ - if (my_sendfile_func == NULL) { - return IOS_UNSUPPORTED; - } else { - sendfilevec_t sfv; - size_t numBytes = 0; - jlong result; + sfv.sfv_fd = srcFD; + sfv.sfv_flag = 0; + sfv.sfv_off = (off64_t)position; + sfv.sfv_len = count; - sfv.sfv_fd = srcFD; - sfv.sfv_flag = 0; - sfv.sfv_off = (off64_t)position; - sfv.sfv_len = count; - - result = (*my_sendfile_func)(dstFD, &sfv, 1, &numBytes); + result = sendfilev64(dstFD, &sfv, 1, &numBytes); - /* Solaris sendfilev() will return -1 even if some bytes have been - * transferred, so we check numBytes first. - */ - if (numBytes > 0) - return numBytes; - if (result < 0) { - if (errno == EAGAIN) - return IOS_UNAVAILABLE; - if (errno == EOPNOTSUPP) - return IOS_UNSUPPORTED_CASE; - if ((errno == EINVAL) && ((ssize_t)count >= 0)) - return IOS_UNSUPPORTED_CASE; - if (errno == EINTR) - return IOS_INTERRUPTED; - JNU_ThrowIOExceptionWithLastError(env, "Transfer failed"); - return IOS_THROWN; - } - return result; + /* Solaris sendfilev() will return -1 even if some bytes have been + * transferred, so we check numBytes first. + */ + if (numBytes > 0) + return numBytes; + if (result < 0) { + if (errno == EAGAIN) + return IOS_UNAVAILABLE; + if (errno == EOPNOTSUPP) + return IOS_UNSUPPORTED_CASE; + if ((errno == EINVAL) && ((ssize_t)count >= 0)) + return IOS_UNSUPPORTED_CASE; + if (errno == EINTR) + return IOS_INTERRUPTED; + JNU_ThrowIOExceptionWithLastError(env, "Transfer failed"); + return IOS_THROWN; } + return result; +#else + return IOS_UNSUPPORTED_CASE; #endif }