8274113: (fc) Tune FileChannel.transferFrom()

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2022-05-12 18:49:58 +00:00
parent 61cb4b7448
commit 986d87dcc0
4 changed files with 132 additions and 15 deletions

View file

@ -31,6 +31,7 @@
#if defined(__linux__)
#include <sys/sendfile.h>
#include <dlfcn.h>
#elif defined(_AIX)
#include <string.h>
#include <sys/socket.h>
@ -52,11 +53,21 @@
static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
#if defined(__linux__)
typedef ssize_t copy_file_range_func(int, loff_t*, int, loff_t*, size_t,
unsigned int);
static copy_file_range_func* my_copy_file_range_func = NULL;
#endif
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;");
#if defined(__linux__)
my_copy_file_range_func =
(copy_file_range_func*) dlsym(RTLD_DEFAULT, "copy_file_range");
#endif
return pageSize;
}
@ -252,6 +263,38 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
#endif
}
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_transferFrom0(JNIEnv *env, jobject this,
jobject srcFDO, jobject dstFDO,
jlong position, jlong count)
{
#if defined(__linux__)
if (my_copy_file_range_func == NULL)
return IOS_UNSUPPORTED;
jint srcFD = fdval(env, srcFDO);
jint dstFD = fdval(env, dstFDO);
off64_t offset = (off64_t)position;
jlong n = my_copy_file_range_func(srcFD, NULL, dstFD, &offset, count, 0);
if (n < 0) {
if (errno == EAGAIN)
return IOS_UNAVAILABLE;
if ((errno == EINVAL || errno == EXDEV) && ((ssize_t)count >= 0))
return IOS_UNSUPPORTED_CASE;
if (errno == EINTR) {
return IOS_INTERRUPTED;
}
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
return IOS_THROWN;
}
return n;
#else
return IOS_UNSUPPORTED;
#endif
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileChannelImpl_maxDirectTransferSize0(JNIEnv* env, jobject this)
{