< 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 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 >