< prev index next >

src/java.base/unix/native/libnio/ch/FileChannelImpl.c

Print this page

        

*** 45,54 **** --- 45,55 ---- #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,87 **** } JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this, ! jint prot, jlong off, jlong len) { void *mapAddress = 0; jobject fdo = (*env)->GetObjectField(env, this, chan_fd); jint fd = fdval(env, fdo); int protections = 0; int flags = 0; 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; --- 71,91 ---- } JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this, ! 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,107 **** --- 93,143 ---- } 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 with persistent mode 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 with persistent mode 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 >