src/java.base/unix/native/libnio/ch/FileChannelImpl.c
changeset 57804 9b7b9f16dfd9
parent 55753 b9798272720b
child 58679 9c3209ff7550
equal deleted inserted replaced
57803:23e3ab980622 57804:9b7b9f16dfd9
    46 #include "jlong.h"
    46 #include "jlong.h"
    47 #include "nio.h"
    47 #include "nio.h"
    48 #include "nio_util.h"
    48 #include "nio_util.h"
    49 #include "sun_nio_ch_FileChannelImpl.h"
    49 #include "sun_nio_ch_FileChannelImpl.h"
    50 #include "java_lang_Integer.h"
    50 #include "java_lang_Integer.h"
       
    51 #include <assert.h>
    51 
    52 
    52 static jfieldID chan_fd;        /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
    53 static jfieldID chan_fd;        /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
    53 
    54 
    54 JNIEXPORT jlong JNICALL
    55 JNIEXPORT jlong JNICALL
    55 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
    56 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
    71 }
    72 }
    72 
    73 
    73 
    74 
    74 JNIEXPORT jlong JNICALL
    75 JNIEXPORT jlong JNICALL
    75 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
    76 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
    76                                      jint prot, jlong off, jlong len)
    77                                      jint prot, jlong off, jlong len, jboolean map_sync)
    77 {
    78 {
    78     void *mapAddress = 0;
    79     void *mapAddress = 0;
    79     jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
    80     jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
    80     jint fd = fdval(env, fdo);
    81     jint fd = fdval(env, fdo);
    81     int protections = 0;
    82     int protections = 0;
    82     int flags = 0;
    83     int flags = 0;
       
    84 
       
    85     // should never be called with map_sync and prot == PRIVATE
       
    86     assert((prot != sun_nio_ch_FileChannelImpl_MAP_PV) || !map_sync);
    83 
    87 
    84     if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
    88     if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
    85         protections = PROT_READ;
    89         protections = PROT_READ;
    86         flags = MAP_SHARED;
    90         flags = MAP_SHARED;
    87     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
    91     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
    90     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
    94     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
    91         protections =  PROT_WRITE | PROT_READ;
    95         protections =  PROT_WRITE | PROT_READ;
    92         flags = MAP_PRIVATE;
    96         flags = MAP_PRIVATE;
    93     }
    97     }
    94 
    98 
       
    99     // if MAP_SYNC and MAP_SHARED_VALIDATE are not defined then it is
       
   100     // best to define them here. This ensures the code compiles on old
       
   101     // OS releases which do not provide the relevant headers. If run
       
   102     // on the same machine then it will work if the kernel contains
       
   103     // the necessary support otherwise mmap should fail with an
       
   104     // invalid argument error
       
   105 
       
   106 #ifndef MAP_SYNC
       
   107 #define MAP_SYNC 0x80000
       
   108 #endif
       
   109 #ifndef MAP_SHARED_VALIDATE
       
   110 #define MAP_SHARED_VALIDATE 0x03
       
   111 #endif
       
   112 
       
   113     if (map_sync) {
       
   114         // ensure
       
   115         //  1) this is Linux on AArch64 or x86_64
       
   116         //  2) the mmap APIs are available/ at compile time
       
   117 #if !defined(LINUX) || ! (defined(aarch64) || (defined(amd64) && defined(_LP64)))
       
   118         // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
       
   119         JNU_ThrowInternalError(env, "should never call map on platform where MAP_SYNC is unimplemented");
       
   120         return IOS_THROWN;
       
   121 #else
       
   122         flags |= MAP_SYNC | MAP_SHARED_VALIDATE;
       
   123 #endif
       
   124     }
       
   125 
    95     mapAddress = mmap64(
   126     mapAddress = mmap64(
    96         0,                    /* Let OS decide location */
   127         0,                    /* Let OS decide location */
    97         len,                  /* Number of bytes to map */
   128         len,                  /* Number of bytes to map */
    98         protections,          /* File permissions */
   129         protections,          /* File permissions */
    99         flags,                /* Changes are shared */
   130         flags,                /* Changes are shared */
   100         fd,                   /* File descriptor of mapped file */
   131         fd,                   /* File descriptor of mapped file */
   101         off);                 /* Offset into file */
   132         off);                 /* Offset into file */
   102 
   133 
   103     if (mapAddress == MAP_FAILED) {
   134     if (mapAddress == MAP_FAILED) {
       
   135         if (map_sync && errno == ENOTSUP) {
       
   136             JNU_ThrowIOExceptionWithLastError(env, "map with mode MAP_SYNC unsupported");
       
   137             return IOS_THROWN;
       
   138         }
       
   139 
   104         if (errno == ENOMEM) {
   140         if (errno == ENOMEM) {
   105             JNU_ThrowOutOfMemoryError(env, "Map failed");
   141             JNU_ThrowOutOfMemoryError(env, "Map failed");
   106             return IOS_THROWN;
   142             return IOS_THROWN;
   107         }
   143         }
   108         return handle(env, -1, "Map failed");
   144         return handle(env, -1, "Map failed");