< prev index next >
src/java.base/unix/native/libnio/ch/FileChannelImpl.c
Print this page
@@ -45,10 +45,11 @@
#include "jlong.h"
#include "nio.h"
#include "nio_util.h"
#include "sun_nio_ch_FileChannelImpl.h"
#include "java_lang_Integer.h"
+#include <assert.h>
static jfieldID chan_fd; /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
@@ -70,18 +71,21 @@
}
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
- jint prot, jlong off, jlong len)
+ jint prot, jlong off, jlong len, jboolean map_sync)
{
void *mapAddress = 0;
jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
jint fd = fdval(env, fdo);
int protections = 0;
int flags = 0;
+ // should never be called with map_sync and prot == PRIVATE
+ assert((prot != sun_nio_ch_FileChannelImpl_MAP_PV) ||! map_sync);
+
if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
protections = PROT_READ;
flags = MAP_SHARED;
} else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
protections = PROT_WRITE | PROT_READ;
@@ -89,19 +93,51 @@
} else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
protections = PROT_WRITE | PROT_READ;
flags = MAP_PRIVATE;
}
+ // if MAP_SYNC and MAP_SHARED_VALIDATE are not defined then it is
+ // best to define them here. This ensures the code compiles on old
+ // OS releases which do not provide the relevant headers. If run
+ // on the same machine then it will work if the kernel contains
+ // the necessary support otherwise mmap should fail with an
+ // invalid argument error
+
+#ifndef MAP_SYNC
+#define MAP_SYNC 0x80000
+#endif
+#ifndef MAP_SHARED_VALIDATE
+#define MAP_SHARED_VALIDATE 0x03
+#endif
+
+ if (map_sync) {
+ // ensure
+ // 1) this is Linux on AArch64 or x86_64
+ // 2) the mmap APIs are available/ at compile time
+#if !defined(LINUX) || ! (defined(aarch64) || (defined(amd64) && defined(_LP64)))
+ // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
+ JNU_ThrowIOException(env, "map_persistent is not implemented");
+ return IOS_THROWN;
+#else
+ flags |= MAP_SYNC | MAP_SHARED_VALIDATE;
+#endif
+ }
+
mapAddress = mmap64(
0, /* Let OS decide location */
len, /* Number of bytes to map */
protections, /* File permissions */
flags, /* Changes are shared */
fd, /* File descriptor of mapped file */
off); /* Offset into file */
if (mapAddress == MAP_FAILED) {
+ if (map_sync && errno == ENOTSUP) {
+ JNU_ThrowIOExceptionWithLastError(env, "map_persistent is not supported");
+ return IOS_THROWN;
+ }
+
if (errno == ENOMEM) {
JNU_ThrowOutOfMemoryError(env, "Map failed");
return IOS_THROWN;
}
return handle(env, -1, "Map failed");
< prev index next >