< prev index next >

src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java

Print this page




 930     private static final int MAP_RO = 0;
 931     private static final int MAP_RW = 1;
 932     private static final int MAP_PV = 2;
 933 
 934     public MappedByteBuffer map(MapMode mode, long position, long size)
 935         throws IOException
 936     {
 937         ensureOpen();
 938         if (mode == null)
 939             throw new NullPointerException("Mode is null");
 940         if (position < 0L)
 941             throw new IllegalArgumentException("Negative position");
 942         if (size < 0L)
 943             throw new IllegalArgumentException("Negative size");
 944         if (position + size < 0)
 945             throw new IllegalArgumentException("Position + size overflow");
 946         if (size > Integer.MAX_VALUE)
 947             throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
 948 
 949         int imode = -1;

 950         if (mode == MapMode.READ_ONLY)
 951             imode = MAP_RO;
 952         else if (mode == MapMode.READ_WRITE)
 953             imode = MAP_RW;
 954         else if (mode == MapMode.PRIVATE)
 955             imode = MAP_PV;








 956         assert (imode >= 0);
 957         if ((mode != MapMode.READ_ONLY) && !writable)
 958             throw new NonWritableChannelException();
 959         if (!readable)
 960             throw new NonReadableChannelException();
 961 
 962         long addr = -1;
 963         int ti = -1;
 964         try {
 965             beginBlocking();
 966             ti = threads.add();
 967             if (!isOpen())
 968                 return null;
 969 
 970             long mapSize;
 971             int pagePosition;
 972             synchronized (positionLock) {
 973                 long filesize;
 974                 do {
 975                     filesize = nd.size(fd);


 978                     return null;
 979 
 980                 if (filesize < position + size) { // Extend file size
 981                     if (!writable) {
 982                         throw new IOException("Channel not open for writing " +
 983                             "- cannot extend file to required size");
 984                     }
 985                     int rv;
 986                     do {
 987                         rv = nd.truncate(fd, position + size);
 988                     } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 989                     if (!isOpen())
 990                         return null;
 991                 }
 992 
 993                 if (size == 0) {
 994                     addr = 0;
 995                     // a valid file descriptor is not required
 996                     FileDescriptor dummy = new FileDescriptor();
 997                     if ((!writable) || (imode == MAP_RO))
 998                         return Util.newMappedByteBufferR(0, 0, dummy, null);
 999                     else
1000                         return Util.newMappedByteBuffer(0, 0, dummy, null);
1001                 }
1002 
1003                 pagePosition = (int)(position % allocationGranularity);
1004                 long mapPosition = position - pagePosition;
1005                 mapSize = size + pagePosition;
1006                 try {
1007                     // If map0 did not throw an exception, the address is valid
1008                     addr = map0(imode, mapPosition, mapSize);
1009                 } catch (OutOfMemoryError x) {
1010                     // An OutOfMemoryError may indicate that we've exhausted
1011                     // memory so force gc and re-attempt map
1012                     System.gc();
1013                     try {
1014                         Thread.sleep(100);
1015                     } catch (InterruptedException y) {
1016                         Thread.currentThread().interrupt();
1017                     }
1018                     try {
1019                         addr = map0(imode, mapPosition, mapSize);
1020                     } catch (OutOfMemoryError y) {
1021                         // After a second OOME, fail
1022                         throw new IOException("Map failed", y);
1023                     }
1024                 }
1025             } // synchronized
1026 
1027             // On Windows, and potentially other platforms, we need an open
1028             // file descriptor for some mapping operations.
1029             FileDescriptor mfd;
1030             try {
1031                 mfd = nd.duplicateForMapping(fd);
1032             } catch (IOException ioe) {
1033                 unmap0(addr, mapSize);
1034                 throw ioe;
1035             }
1036 
1037             assert (IOStatus.checkAll(addr));
1038             assert (addr % allocationGranularity == 0);
1039             int isize = (int)size;
1040             Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
1041             if ((!writable) || (imode == MAP_RO)) {
1042                 return Util.newMappedByteBufferR(isize,
1043                                                  addr + pagePosition,
1044                                                  mfd,
1045                                                  um);

1046             } else {
1047                 return Util.newMappedByteBuffer(isize,
1048                                                 addr + pagePosition,
1049                                                 mfd,
1050                                                 um);

1051             }
1052         } finally {
1053             threads.remove(ti);
1054             endBlocking(IOStatus.checkAll(addr));
1055         }
1056     }
1057 
1058     /**
1059      * Invoked by sun.management.ManagementFactoryHelper to create the management
1060      * interface for mapped buffers.
1061      */
1062     public static JavaNioAccess.BufferPool getMappedBufferPool() {
1063         return new JavaNioAccess.BufferPool() {
1064             @Override
1065             public String getName() {
1066                 return "mapped";
1067             }
1068             @Override
1069             public long getCount() {
1070                 return Unmapper.count;


1184         } finally {
1185             threads.remove(ti);
1186         }
1187     }
1188 
1189     void release(FileLockImpl fli) throws IOException {
1190         int ti = threads.add();
1191         try {
1192             ensureOpen();
1193             nd.release(fd, fli.position(), fli.size());
1194         } finally {
1195             threads.remove(ti);
1196         }
1197         assert fileLockTable != null;
1198         fileLockTable.remove(fli);
1199     }
1200 
1201     // -- Native methods --
1202 
1203     // Creates a new mapping
1204     private native long map0(int prot, long position, long length)
1205         throws IOException;
1206 
1207     // Removes an existing mapping
1208     private static native int unmap0(long address, long length);
1209 
1210     // Transfers from src to dst, or returns -2 if kernel can't do that
1211     private native long transferTo0(FileDescriptor src, long position,
1212                                     long count, FileDescriptor dst);
1213 
1214     // Caches fieldIDs
1215     private static native long initIDs();
1216 
1217     static {
1218         IOUtil.load();
1219         allocationGranularity = initIDs();
1220     }
1221 }


 930     private static final int MAP_RO = 0;
 931     private static final int MAP_RW = 1;
 932     private static final int MAP_PV = 2;
 933 
 934     public MappedByteBuffer map(MapMode mode, long position, long size)
 935         throws IOException
 936     {
 937         ensureOpen();
 938         if (mode == null)
 939             throw new NullPointerException("Mode is null");
 940         if (position < 0L)
 941             throw new IllegalArgumentException("Negative position");
 942         if (size < 0L)
 943             throw new IllegalArgumentException("Negative size");
 944         if (position + size < 0)
 945             throw new IllegalArgumentException("Position + size overflow");
 946         if (size > Integer.MAX_VALUE)
 947             throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
 948 
 949         int imode = -1;
 950         boolean isPersistent = false;
 951         if (mode == MapMode.READ_ONLY)
 952             imode = MAP_RO;
 953         else if (mode == MapMode.READ_WRITE)
 954             imode = MAP_RW;
 955         else if (mode == MapMode.PRIVATE) {
 956             imode = MAP_PV;
 957         } else if (mode == MapMode.READ_ONLY_PERSISTENT) {
 958             imode = MAP_RO;
 959             isPersistent = true;
 960         } else if (mode == MapMode.READ_WRITE_PERSISTENT) {
 961             imode = MAP_RW;
 962             isPersistent = true;
 963         }
 964 
 965         assert (imode >= 0);
 966         if ((mode != MapMode.READ_ONLY) && !writable)
 967             throw new NonWritableChannelException();
 968         if (!readable)
 969             throw new NonReadableChannelException();
 970 
 971         long addr = -1;
 972         int ti = -1;
 973         try {
 974             beginBlocking();
 975             ti = threads.add();
 976             if (!isOpen())
 977                 return null;
 978 
 979             long mapSize;
 980             int pagePosition;
 981             synchronized (positionLock) {
 982                 long filesize;
 983                 do {
 984                     filesize = nd.size(fd);


 987                     return null;
 988 
 989                 if (filesize < position + size) { // Extend file size
 990                     if (!writable) {
 991                         throw new IOException("Channel not open for writing " +
 992                             "- cannot extend file to required size");
 993                     }
 994                     int rv;
 995                     do {
 996                         rv = nd.truncate(fd, position + size);
 997                     } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 998                     if (!isOpen())
 999                         return null;
1000                 }
1001 
1002                 if (size == 0) {
1003                     addr = 0;
1004                     // a valid file descriptor is not required
1005                     FileDescriptor dummy = new FileDescriptor();
1006                     if ((!writable) || (imode == MAP_RO))
1007                         return Util.newMappedByteBufferR(0, 0, dummy, null, isPersistent);
1008                     else
1009                         return Util.newMappedByteBuffer(0, 0, dummy, null, isPersistent);
1010                 }
1011 
1012                 pagePosition = (int)(position % allocationGranularity);
1013                 long mapPosition = position - pagePosition;
1014                 mapSize = size + pagePosition;
1015                 try {
1016                     // If map0 did not throw an exception, the address is valid
1017                     addr = map0(imode, mapPosition, mapSize, isPersistent);
1018                 } catch (OutOfMemoryError x) {
1019                     // An OutOfMemoryError may indicate that we've exhausted
1020                     // memory so force gc and re-attempt map
1021                     System.gc();
1022                     try {
1023                         Thread.sleep(100);
1024                     } catch (InterruptedException y) {
1025                         Thread.currentThread().interrupt();
1026                     }
1027                     try {
1028                         addr = map0(imode, mapPosition, mapSize, isPersistent);
1029                     } catch (OutOfMemoryError y) {
1030                         // After a second OOME, fail
1031                         throw new IOException("Map failed", y);
1032                     }
1033                 }
1034             } // synchronized
1035 
1036             // On Windows, and potentially other platforms, we need an open
1037             // file descriptor for some mapping operations.
1038             FileDescriptor mfd;
1039             try {
1040                 mfd = nd.duplicateForMapping(fd);
1041             } catch (IOException ioe) {
1042                 unmap0(addr, mapSize);
1043                 throw ioe;
1044             }
1045 
1046             assert (IOStatus.checkAll(addr));
1047             assert (addr % allocationGranularity == 0);
1048             int isize = (int)size;
1049             Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
1050             if ((!writable) || (imode == MAP_RO)) {
1051                 return Util.newMappedByteBufferR(isize,
1052                                                  addr + pagePosition,
1053                                                  mfd,
1054                                                  um,
1055                                                  isPersistent);
1056             } else {
1057                 return Util.newMappedByteBuffer(isize,
1058                                                 addr + pagePosition,
1059                                                 mfd,
1060                                                 um,
1061                                                 isPersistent);
1062             }
1063         } finally {
1064             threads.remove(ti);
1065             endBlocking(IOStatus.checkAll(addr));
1066         }
1067     }
1068 
1069     /**
1070      * Invoked by sun.management.ManagementFactoryHelper to create the management
1071      * interface for mapped buffers.
1072      */
1073     public static JavaNioAccess.BufferPool getMappedBufferPool() {
1074         return new JavaNioAccess.BufferPool() {
1075             @Override
1076             public String getName() {
1077                 return "mapped";
1078             }
1079             @Override
1080             public long getCount() {
1081                 return Unmapper.count;


1195         } finally {
1196             threads.remove(ti);
1197         }
1198     }
1199 
1200     void release(FileLockImpl fli) throws IOException {
1201         int ti = threads.add();
1202         try {
1203             ensureOpen();
1204             nd.release(fd, fli.position(), fli.size());
1205         } finally {
1206             threads.remove(ti);
1207         }
1208         assert fileLockTable != null;
1209         fileLockTable.remove(fli);
1210     }
1211 
1212     // -- Native methods --
1213 
1214     // Creates a new mapping
1215     private native long map0(int prot, long position, long length, boolean isPersistent)
1216         throws IOException;
1217 
1218     // Removes an existing mapping
1219     private static native int unmap0(long address, long length);
1220 
1221     // Transfers from src to dst, or returns -2 if kernel can't do that
1222     private native long transferTo0(FileDescriptor src, long position,
1223                                     long count, FileDescriptor dst);
1224 
1225     // Caches fieldIDs
1226     private static native long initIDs();
1227 
1228     static {
1229         IOUtil.load();
1230         allocationGranularity = initIDs();
1231     }
1232 }
< prev index next >