src/java.base/unix/native/libnio/ch/FileChannelImpl.c
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 49897 117501815bed
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    30 #include <unistd.h>
    30 #include <unistd.h>
    31 
    31 
    32 #if defined(__linux__) || defined(__solaris__)
    32 #if defined(__linux__) || defined(__solaris__)
    33 #include <sys/sendfile.h>
    33 #include <sys/sendfile.h>
    34 #elif defined(_AIX)
    34 #elif defined(_AIX)
       
    35 #include <string.h>
    35 #include <sys/socket.h>
    36 #include <sys/socket.h>
    36 #elif defined(_ALLBSD_SOURCE)
    37 #elif defined(_ALLBSD_SOURCE)
    37 #include <sys/socket.h>
    38 #include <sys/socket.h>
    38 #include <sys/uio.h>
    39 #include <sys/uio.h>
    39 #define lseek64 lseek
    40 #define lseek64 lseek
    45 #include "jlong.h"
    46 #include "jlong.h"
    46 #include "nio.h"
    47 #include "nio.h"
    47 #include "nio_util.h"
    48 #include "nio_util.h"
    48 #include "sun_nio_ch_FileChannelImpl.h"
    49 #include "sun_nio_ch_FileChannelImpl.h"
    49 #include "java_lang_Integer.h"
    50 #include "java_lang_Integer.h"
       
    51 #include <assert.h>
    50 
    52 
    51 static jfieldID chan_fd;        /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
    53 static jfieldID chan_fd;        /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
    52 
    54 
    53 JNIEXPORT jlong JNICALL
    55 JNIEXPORT jlong JNICALL
    54 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
    56 Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
    70 }
    72 }
    71 
    73 
    72 
    74 
    73 JNIEXPORT jlong JNICALL
    75 JNIEXPORT jlong JNICALL
    74 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
    76 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
    75                                      jint prot, jlong off, jlong len)
    77                                      jint prot, jlong off, jlong len, jboolean map_sync)
    76 {
    78 {
    77     void *mapAddress = 0;
    79     void *mapAddress = 0;
    78     jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
    80     jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
    79     jint fd = fdval(env, fdo);
    81     jint fd = fdval(env, fdo);
    80     int protections = 0;
    82     int protections = 0;
    81     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);
    82 
    87 
    83     if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
    88     if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
    84         protections = PROT_READ;
    89         protections = PROT_READ;
    85         flags = MAP_SHARED;
    90         flags = MAP_SHARED;
    86     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
    91     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
    89     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
    94     } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
    90         protections =  PROT_WRITE | PROT_READ;
    95         protections =  PROT_WRITE | PROT_READ;
    91         flags = MAP_PRIVATE;
    96         flags = MAP_PRIVATE;
    92     }
    97     }
    93 
    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 
    94     mapAddress = mmap64(
   126     mapAddress = mmap64(
    95         0,                    /* Let OS decide location */
   127         0,                    /* Let OS decide location */
    96         len,                  /* Number of bytes to map */
   128         len,                  /* Number of bytes to map */
    97         protections,          /* File permissions */
   129         protections,          /* File permissions */
    98         flags,                /* Changes are shared */
   130         flags,                /* Changes are shared */
    99         fd,                   /* File descriptor of mapped file */
   131         fd,                   /* File descriptor of mapped file */
   100         off);                 /* Offset into file */
   132         off);                 /* Offset into file */
   101 
   133 
   102     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 
   103         if (errno == ENOMEM) {
   140         if (errno == ENOMEM) {
   104             JNU_ThrowOutOfMemoryError(env, "Map failed");
   141             JNU_ThrowOutOfMemoryError(env, "Map failed");
   105             return IOS_THROWN;
   142             return IOS_THROWN;
   106         }
   143         }
   107         return handle(env, -1, "Map failed");
   144         return handle(env, -1, "Map failed");