Skip to content

Commit e195897

Browse files
author
Brian Burkhalter
committed
8294068: Unconditional and eager load of nio library since JDK-8264744
Reviewed-by: alanb, redestad
1 parent 84d7ff6 commit e195897

File tree

4 files changed

+102
-161
lines changed

4 files changed

+102
-161
lines changed

src/java.base/linux/classes/sun/nio/fs/LinuxFileSystem.java

-28
Original file line numberDiff line numberDiff line change
@@ -158,32 +158,4 @@ int directCopy(int dst, int src, long addressToPollForCancel)
158158

159159
return directCopy0(dst, src, addressToPollForCancel);
160160
}
161-
162-
// -- native methods --
163-
164-
private static native void init();
165-
166-
/**
167-
* Copies data between file descriptors {@code src} and {@code dst} using
168-
* a platform-specific function or system call possibly having kernel
169-
* support.
170-
*
171-
* @param dst destination file descriptor
172-
* @param src source file descriptor
173-
* @param addressToPollForCancel address to check for cancellation
174-
* (a non-zero value written to this address indicates cancel)
175-
*
176-
* @return 0 on success, UNAVAILABLE if the platform function would block,
177-
* UNSUPPORTED_CASE if the call does not work with the given
178-
* parameters, or UNSUPPORTED if direct copying is not supported
179-
* on this platform
180-
*/
181-
private static native int directCopy0(int dst, int src,
182-
long addressToPollForCancel)
183-
throws UnixException;
184-
185-
static {
186-
jdk.internal.loader.BootLoader.loadLibrary("nio");
187-
init();
188-
}
189161
}

src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java

+18
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@ static native int getmntent0(long fp, UnixMountEntry entry, long buffer, int buf
6868
static native int posix_fadvise(int fd, long offset, long len, int advice)
6969
throws UnixException;
7070

71+
/**
72+
* Copies data between file descriptors {@code src} and {@code dst} using
73+
* a platform-specific function or system call possibly having kernel
74+
* support.
75+
*
76+
* @param dst destination file descriptor
77+
* @param src source file descriptor
78+
* @param addressToPollForCancel address to check for cancellation
79+
* (a non-zero value written to this address indicates cancel)
80+
*
81+
* @return 0 on success, UNAVAILABLE if the platform function would block,
82+
* UNSUPPORTED_CASE if the call does not work with the given
83+
* parameters, or UNSUPPORTED if direct copying is not supported
84+
* on this platform
85+
*/
86+
static native int directCopy0(int dst, int src, long addressToPollForCancel)
87+
throws UnixException;
88+
7189
// initialize
7290
private static native void init();
7391

src/java.base/linux/native/libnio/fs/LinuxFileSystem.c

-133
This file was deleted.

src/java.base/linux/native/libnio/fs/LinuxNativeDispatcher.c

+84
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,34 @@
2828
#include "jvm.h"
2929
#include "jlong.h"
3030

31+
#include "nio.h"
32+
3133
#include <stdio.h>
3234
#include <string.h>
3335
#include <dlfcn.h>
3436
#include <errno.h>
3537
#include <mntent.h>
3638
#include <fcntl.h>
3739

40+
#include <sys/sendfile.h>
41+
3842
#include "sun_nio_fs_LinuxNativeDispatcher.h"
3943

4044
static jfieldID entry_name;
4145
static jfieldID entry_dir;
4246
static jfieldID entry_fstype;
4347
static jfieldID entry_options;
4448

49+
typedef ssize_t copy_file_range_func(int, loff_t*, int, loff_t*, size_t,
50+
unsigned int);
51+
static copy_file_range_func* my_copy_file_range_func = NULL;
52+
53+
#define RESTARTABLE(_cmd, _result) do { \
54+
do { \
55+
_result = _cmd; \
56+
} while((_result == -1) && (errno == EINTR)); \
57+
} while(0)
58+
4559
static void throwUnixException(JNIEnv* env, int errnum) {
4660
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
4761
"(I)V", errnum);
@@ -63,6 +77,9 @@ Java_sun_nio_fs_LinuxNativeDispatcher_init(JNIEnv *env, jclass clazz)
6377
CHECK_NULL(entry_fstype);
6478
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
6579
CHECK_NULL(entry_options);
80+
81+
my_copy_file_range_func =
82+
(copy_file_range_func*) dlsym(RTLD_DEFAULT, "copy_file_range");
6683
}
6784

6885
JNIEXPORT jlong JNICALL
@@ -150,3 +167,70 @@ Java_sun_nio_fs_LinuxNativeDispatcher_posix_1fadvise(JNIEnv* env, jclass this,
150167
{
151168
return posix_fadvise64((int)fd, (off64_t)offset, (off64_t)len, (int)advice);
152169
}
170+
171+
// Copy all bytes from src to dst, within the kernel if possible,
172+
// and return zero, otherwise return the appropriate status code.
173+
//
174+
// Return value
175+
// 0 on success
176+
// IOS_UNAVAILABLE if the platform function would block
177+
// IOS_UNSUPPORTED_CASE if the call does not work with the given parameters
178+
// IOS_UNSUPPORTED if direct copying is not supported on this platform
179+
// IOS_THROWN if a Java exception is thrown
180+
//
181+
JNIEXPORT jint JNICALL
182+
Java_sun_nio_fs_LinuxNativeDispatcher_directCopy0
183+
(JNIEnv* env, jclass this, jint dst, jint src, jlong cancelAddress)
184+
{
185+
volatile jint* cancel = (jint*)jlong_to_ptr(cancelAddress);
186+
187+
// Transfer within the kernel
188+
const size_t count = cancel != NULL ?
189+
1048576 : // 1 MB to give cancellation a chance
190+
0x7ffff000; // maximum number of bytes that sendfile() can transfer
191+
192+
ssize_t bytes_sent;
193+
if (my_copy_file_range_func != NULL) {
194+
do {
195+
RESTARTABLE(my_copy_file_range_func(src, NULL, dst, NULL, count, 0),
196+
bytes_sent);
197+
if (bytes_sent < 0) {
198+
switch (errno) {
199+
case EINVAL:
200+
case ENOSYS:
201+
case EXDEV:
202+
// ignore and try sendfile()
203+
break;
204+
default:
205+
JNU_ThrowIOExceptionWithLastError(env, "Copy failed");
206+
return IOS_THROWN;
207+
}
208+
}
209+
if (cancel != NULL && *cancel != 0) {
210+
throwUnixException(env, ECANCELED);
211+
return IOS_THROWN;
212+
}
213+
} while (bytes_sent > 0);
214+
215+
if (bytes_sent == 0)
216+
return 0;
217+
}
218+
219+
do {
220+
RESTARTABLE(sendfile64(dst, src, NULL, count), bytes_sent);
221+
if (bytes_sent < 0) {
222+
if (errno == EAGAIN)
223+
return IOS_UNAVAILABLE;
224+
if (errno == EINVAL || errno == ENOSYS)
225+
return IOS_UNSUPPORTED_CASE;
226+
throwUnixException(env, errno);
227+
return IOS_THROWN;
228+
}
229+
if (cancel != NULL && *cancel != 0) {
230+
throwUnixException(env, ECANCELED);
231+
return IOS_THROWN;
232+
}
233+
} while (bytes_sent > 0);
234+
235+
return 0;
236+
}

0 commit comments

Comments
 (0)