1 /*
2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
881 if (mode == MapMode.READ_ONLY)
882 imode = MAP_RO;
883 else if (mode == MapMode.READ_WRITE)
884 imode = MAP_RW;
885 else if (mode == MapMode.PRIVATE)
886 imode = MAP_PV;
887 assert (imode >= 0);
888 if ((mode != MapMode.READ_ONLY) && !writable)
889 throw new NonWritableChannelException();
890 if (!readable)
891 throw new NonReadableChannelException();
892
893 long addr = -1;
894 int ti = -1;
895 try {
896 begin();
897 ti = threads.add();
898 if (!isOpen())
899 return null;
900
901 long filesize;
902 do {
903 filesize = nd.size(fd);
904 } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
905 if (!isOpen())
906 return null;
907
908 if (filesize < position + size) { // Extend file size
909 if (!writable) {
910 throw new IOException("Channel not open for writing " +
911 "- cannot extend file to required size");
912 }
913 int rv;
914 do {
915 rv = nd.truncate(fd, position + size);
916 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
917 if (!isOpen())
918 return null;
919 }
920 if (size == 0) {
921 addr = 0;
922 // a valid file descriptor is not required
923 FileDescriptor dummy = new FileDescriptor();
924 if ((!writable) || (imode == MAP_RO))
925 return Util.newMappedByteBufferR(0, 0, dummy, null);
926 else
927 return Util.newMappedByteBuffer(0, 0, dummy, null);
928 }
929
930 int pagePosition = (int)(position % allocationGranularity);
931 long mapPosition = position - pagePosition;
932 long mapSize = size + pagePosition;
933 try {
934 // If no exception was thrown from map0, the address is valid
935 addr = map0(imode, mapPosition, mapSize);
936 } catch (OutOfMemoryError x) {
937 // An OutOfMemoryError may indicate that we've exhausted memory
938 // so force gc and re-attempt map
939 System.gc();
940 try {
941 Thread.sleep(100);
942 } catch (InterruptedException y) {
943 Thread.currentThread().interrupt();
944 }
945 try {
946 addr = map0(imode, mapPosition, mapSize);
947 } catch (OutOfMemoryError y) {
948 // After a second OOME, fail
949 throw new IOException("Map failed", y);
950 }
951 }
952
953 // On Windows, and potentially other platforms, we need an open
954 // file descriptor for some mapping operations.
955 FileDescriptor mfd;
956 try {
957 mfd = nd.duplicateForMapping(fd);
958 } catch (IOException ioe) {
959 unmap0(addr, mapSize);
960 throw ioe;
961 }
962
963 assert (IOStatus.checkAll(addr));
964 assert (addr % allocationGranularity == 0);
965 int isize = (int)size;
966 Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
967 if ((!writable) || (imode == MAP_RO)) {
968 return Util.newMappedByteBufferR(isize,
969 addr + pagePosition,
970 mfd,
971 um);
|
1 /*
2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
881 if (mode == MapMode.READ_ONLY)
882 imode = MAP_RO;
883 else if (mode == MapMode.READ_WRITE)
884 imode = MAP_RW;
885 else if (mode == MapMode.PRIVATE)
886 imode = MAP_PV;
887 assert (imode >= 0);
888 if ((mode != MapMode.READ_ONLY) && !writable)
889 throw new NonWritableChannelException();
890 if (!readable)
891 throw new NonReadableChannelException();
892
893 long addr = -1;
894 int ti = -1;
895 try {
896 begin();
897 ti = threads.add();
898 if (!isOpen())
899 return null;
900
901 long mapSize;
902 int pagePosition;
903 synchronized (positionLock) {
904 long filesize;
905 do {
906 filesize = nd.size(fd);
907 } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
908 if (!isOpen())
909 return null;
910
911 if (filesize < position + size) { // Extend file size
912 if (!writable) {
913 throw new IOException("Channel not open for writing " +
914 "- cannot extend file to required size");
915 }
916 int rv;
917 do {
918 rv = nd.allocate(fd, position + size);
919 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
920 if (!isOpen())
921 return null;
922 }
923
924 if (size == 0) {
925 addr = 0;
926 // a valid file descriptor is not required
927 FileDescriptor dummy = new FileDescriptor();
928 if ((!writable) || (imode == MAP_RO))
929 return Util.newMappedByteBufferR(0, 0, dummy, null);
930 else
931 return Util.newMappedByteBuffer(0, 0, dummy, null);
932 }
933
934 pagePosition = (int)(position % allocationGranularity);
935 long mapPosition = position - pagePosition;
936 mapSize = size + pagePosition;
937 try {
938 // If map0 did not throw an exception, the address is valid
939 addr = map0(imode, mapPosition, mapSize);
940 } catch (OutOfMemoryError x) {
941 // An OutOfMemoryError may indicate that we've exhausted
942 // memory so force gc and re-attempt map
943 System.gc();
944 try {
945 Thread.sleep(100);
946 } catch (InterruptedException y) {
947 Thread.currentThread().interrupt();
948 }
949 try {
950 addr = map0(imode, mapPosition, mapSize);
951 } catch (OutOfMemoryError y) {
952 // After a second OOME, fail
953 throw new IOException("Map failed", y);
954 }
955 }
956 } // synchronized
957
958 // On Windows, and potentially other platforms, we need an open
959 // file descriptor for some mapping operations.
960 FileDescriptor mfd;
961 try {
962 mfd = nd.duplicateForMapping(fd);
963 } catch (IOException ioe) {
964 unmap0(addr, mapSize);
965 throw ioe;
966 }
967
968 assert (IOStatus.checkAll(addr));
969 assert (addr % allocationGranularity == 0);
970 int isize = (int)size;
971 Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
972 if ((!writable) || (imode == MAP_RO)) {
973 return Util.newMappedByteBufferR(isize,
974 addr + pagePosition,
975 mfd,
976 um);
|