src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java
changeset 47428 d72d7d55c765
parent 47332 b87d7b5d5ded
child 47460 b6d959fae9ef
equal deleted inserted replaced
47427:251676148c62 47428:d72d7d55c765
    39 import java.nio.channels.NonWritableChannelException;
    39 import java.nio.channels.NonWritableChannelException;
    40 import java.nio.channels.OverlappingFileLockException;
    40 import java.nio.channels.OverlappingFileLockException;
    41 import java.nio.channels.ReadableByteChannel;
    41 import java.nio.channels.ReadableByteChannel;
    42 import java.nio.channels.SelectableChannel;
    42 import java.nio.channels.SelectableChannel;
    43 import java.nio.channels.WritableByteChannel;
    43 import java.nio.channels.WritableByteChannel;
       
    44 import java.nio.file.Files;
       
    45 import java.nio.file.FileStore;
       
    46 import java.nio.file.FileSystemException;
       
    47 import java.nio.file.Path;
       
    48 import java.nio.file.Paths;
    44 import java.util.ArrayList;
    49 import java.util.ArrayList;
    45 import java.util.List;
    50 import java.util.List;
    46 
    51 
    47 import jdk.internal.misc.JavaIOFileDescriptorAccess;
    52 import jdk.internal.misc.JavaIOFileDescriptorAccess;
    48 import jdk.internal.misc.JavaNioAccess;
    53 import jdk.internal.misc.JavaNioAccess;
    85     private final Object positionLock = new Object();
    90     private final Object positionLock = new Object();
    86 
    91 
    87     // Positional-read is not interruptible
    92     // Positional-read is not interruptible
    88     private volatile boolean uninterruptible;
    93     private volatile boolean uninterruptible;
    89 
    94 
       
    95     // DirectIO flag
       
    96     private final boolean direct;
       
    97 
       
    98     // IO alignment value for DirectIO
       
    99     private final int alignment;
       
   100 
    90     // Cleanable with an action which closes this channel's file descriptor
   101     // Cleanable with an action which closes this channel's file descriptor
    91     private final Cleanable closer;
   102     private final Cleanable closer;
    92 
   103 
    93     private static class Closer implements Runnable {
   104     private static class Closer implements Runnable {
    94         private final FileDescriptor fd;
   105         private final FileDescriptor fd;
   101             fdAccess.close(fd);
   112             fdAccess.close(fd);
   102         }
   113         }
   103     }
   114     }
   104 
   115 
   105     private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
   116     private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
   106                             boolean writable, Object parent)
   117                             boolean writable, boolean direct, Object parent)
   107     {
   118     {
   108         this.fd = fd;
   119         this.fd = fd;
   109         this.readable = readable;
   120         this.readable = readable;
   110         this.writable = writable;
   121         this.writable = writable;
   111         this.parent = parent;
   122         this.parent = parent;
   112         this.path = path;
   123         this.path = path;
       
   124         this.direct = direct;
   113         this.nd = new FileDispatcherImpl();
   125         this.nd = new FileDispatcherImpl();
       
   126         if (direct) {
       
   127             assert path != null;
       
   128             this.alignment = nd.setDirectIO(fd, path);
       
   129         } else {
       
   130             this.alignment = -1;
       
   131         }
       
   132 
   114         // Register a cleaning action if and only if there is no parent
   133         // Register a cleaning action if and only if there is no parent
   115         // as the parent will take care of closing the file descriptor.
   134         // as the parent will take care of closing the file descriptor.
   116         // FileChannel is used by the LambdaMetaFactory so a lambda cannot
   135         // FileChannel is used by the LambdaMetaFactory so a lambda cannot
   117         // be used here hence we use a nested class instead.
   136         // be used here hence we use a nested class instead.
   118         this.closer = parent != null ? null :
   137         this.closer = parent != null ? null :
   123     // and RandomAccessFile.getChannel()
   142     // and RandomAccessFile.getChannel()
   124     public static FileChannel open(FileDescriptor fd, String path,
   143     public static FileChannel open(FileDescriptor fd, String path,
   125                                    boolean readable, boolean writable,
   144                                    boolean readable, boolean writable,
   126                                    Object parent)
   145                                    Object parent)
   127     {
   146     {
   128         return new FileChannelImpl(fd, path, readable, writable, parent);
   147         return new FileChannelImpl(fd, path, readable, writable, false, parent);
       
   148     }
       
   149 
       
   150     public static FileChannel open(FileDescriptor fd, String path,
       
   151                                    boolean readable, boolean writable,
       
   152                                    boolean direct, Object parent)
       
   153     {
       
   154         return new FileChannelImpl(fd, path, readable, writable, direct, parent);
   129     }
   155     }
   130 
   156 
   131     private void ensureOpen() throws IOException {
   157     private void ensureOpen() throws IOException {
   132         if (!isOpen())
   158         if (!isOpen())
   133             throw new ClosedChannelException();
   159             throw new ClosedChannelException();
   179     public int read(ByteBuffer dst) throws IOException {
   205     public int read(ByteBuffer dst) throws IOException {
   180         ensureOpen();
   206         ensureOpen();
   181         if (!readable)
   207         if (!readable)
   182             throw new NonReadableChannelException();
   208             throw new NonReadableChannelException();
   183         synchronized (positionLock) {
   209         synchronized (positionLock) {
       
   210             if (direct)
       
   211                 Util.checkChannelPositionAligned(position(), alignment);
   184             int n = 0;
   212             int n = 0;
   185             int ti = -1;
   213             int ti = -1;
   186             try {
   214             try {
   187                 begin();
   215                 begin();
   188                 ti = threads.add();
   216                 ti = threads.add();
   189                 if (!isOpen())
   217                 if (!isOpen())
   190                     return 0;
   218                     return 0;
   191                 do {
   219                 do {
   192                     n = IOUtil.read(fd, dst, -1, nd);
   220                     n = IOUtil.read(fd, dst, -1, direct, alignment, nd);
   193                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   221                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   194                 return IOStatus.normalize(n);
   222                 return IOStatus.normalize(n);
   195             } finally {
   223             } finally {
   196                 threads.remove(ti);
   224                 threads.remove(ti);
   197                 end(n > 0);
   225                 end(n > 0);
   207             throw new IndexOutOfBoundsException();
   235             throw new IndexOutOfBoundsException();
   208         ensureOpen();
   236         ensureOpen();
   209         if (!readable)
   237         if (!readable)
   210             throw new NonReadableChannelException();
   238             throw new NonReadableChannelException();
   211         synchronized (positionLock) {
   239         synchronized (positionLock) {
       
   240             if (direct)
       
   241                 Util.checkChannelPositionAligned(position(), alignment);
   212             long n = 0;
   242             long n = 0;
   213             int ti = -1;
   243             int ti = -1;
   214             try {
   244             try {
   215                 begin();
   245                 begin();
   216                 ti = threads.add();
   246                 ti = threads.add();
   217                 if (!isOpen())
   247                 if (!isOpen())
   218                     return 0;
   248                     return 0;
   219                 do {
   249                 do {
   220                     n = IOUtil.read(fd, dsts, offset, length, nd);
   250                     n = IOUtil.read(fd, dsts, offset, length,
       
   251                             direct, alignment, nd);
   221                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   252                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   222                 return IOStatus.normalize(n);
   253                 return IOStatus.normalize(n);
   223             } finally {
   254             } finally {
   224                 threads.remove(ti);
   255                 threads.remove(ti);
   225                 end(n > 0);
   256                 end(n > 0);
   231     public int write(ByteBuffer src) throws IOException {
   262     public int write(ByteBuffer src) throws IOException {
   232         ensureOpen();
   263         ensureOpen();
   233         if (!writable)
   264         if (!writable)
   234             throw new NonWritableChannelException();
   265             throw new NonWritableChannelException();
   235         synchronized (positionLock) {
   266         synchronized (positionLock) {
       
   267             if (direct)
       
   268                 Util.checkChannelPositionAligned(position(), alignment);
   236             int n = 0;
   269             int n = 0;
   237             int ti = -1;
   270             int ti = -1;
   238             try {
   271             try {
   239                 begin();
   272                 begin();
   240                 ti = threads.add();
   273                 ti = threads.add();
   241                 if (!isOpen())
   274                 if (!isOpen())
   242                     return 0;
   275                     return 0;
   243                 do {
   276                 do {
   244                     n = IOUtil.write(fd, src, -1, nd);
   277                     n = IOUtil.write(fd, src, -1, direct, alignment, nd);
   245                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   278                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   246                 return IOStatus.normalize(n);
   279                 return IOStatus.normalize(n);
   247             } finally {
   280             } finally {
   248                 threads.remove(ti);
   281                 threads.remove(ti);
   249                 end(n > 0);
   282                 end(n > 0);
   259             throw new IndexOutOfBoundsException();
   292             throw new IndexOutOfBoundsException();
   260         ensureOpen();
   293         ensureOpen();
   261         if (!writable)
   294         if (!writable)
   262             throw new NonWritableChannelException();
   295             throw new NonWritableChannelException();
   263         synchronized (positionLock) {
   296         synchronized (positionLock) {
       
   297             if (direct)
       
   298                 Util.checkChannelPositionAligned(position(), alignment);
   264             long n = 0;
   299             long n = 0;
   265             int ti = -1;
   300             int ti = -1;
   266             try {
   301             try {
   267                 begin();
   302                 begin();
   268                 ti = threads.add();
   303                 ti = threads.add();
   269                 if (!isOpen())
   304                 if (!isOpen())
   270                     return 0;
   305                     return 0;
   271                 do {
   306                 do {
   272                     n = IOUtil.write(fd, srcs, offset, length, nd);
   307                     n = IOUtil.write(fd, srcs, offset, length,
       
   308                             direct, alignment, nd);
   273                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   309                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
   274                 return IOStatus.normalize(n);
   310                 return IOStatus.normalize(n);
   275             } finally {
   311             } finally {
   276                 threads.remove(ti);
   312                 threads.remove(ti);
   277                 end(n > 0);
   313                 end(n > 0);
   750             throw new NullPointerException();
   786             throw new NullPointerException();
   751         if (position < 0)
   787         if (position < 0)
   752             throw new IllegalArgumentException("Negative position");
   788             throw new IllegalArgumentException("Negative position");
   753         if (!readable)
   789         if (!readable)
   754             throw new NonReadableChannelException();
   790             throw new NonReadableChannelException();
       
   791         if (direct)
       
   792             Util.checkChannelPositionAligned(position, alignment);
   755         ensureOpen();
   793         ensureOpen();
   756         if (nd.needsPositionLock()) {
   794         if (nd.needsPositionLock()) {
   757             synchronized (positionLock) {
   795             synchronized (positionLock) {
   758                 return readInternal(dst, position);
   796                 return readInternal(dst, position);
   759             }
   797             }
   772             if (interruptible) begin();
   810             if (interruptible) begin();
   773             ti = threads.add();
   811             ti = threads.add();
   774             if (!isOpen())
   812             if (!isOpen())
   775                 return -1;
   813                 return -1;
   776             do {
   814             do {
   777                 n = IOUtil.read(fd, dst, position, nd);
   815                 n = IOUtil.read(fd, dst, position, direct, alignment, nd);
   778             } while ((n == IOStatus.INTERRUPTED) && isOpen());
   816             } while ((n == IOStatus.INTERRUPTED) && isOpen());
   779             return IOStatus.normalize(n);
   817             return IOStatus.normalize(n);
   780         } finally {
   818         } finally {
   781             threads.remove(ti);
   819             threads.remove(ti);
   782             if (interruptible) end(n > 0);
   820             if (interruptible) end(n > 0);
   789             throw new NullPointerException();
   827             throw new NullPointerException();
   790         if (position < 0)
   828         if (position < 0)
   791             throw new IllegalArgumentException("Negative position");
   829             throw new IllegalArgumentException("Negative position");
   792         if (!writable)
   830         if (!writable)
   793             throw new NonWritableChannelException();
   831             throw new NonWritableChannelException();
       
   832         if (direct)
       
   833             Util.checkChannelPositionAligned(position, alignment);
   794         ensureOpen();
   834         ensureOpen();
   795         if (nd.needsPositionLock()) {
   835         if (nd.needsPositionLock()) {
   796             synchronized (positionLock) {
   836             synchronized (positionLock) {
   797                 return writeInternal(src, position);
   837                 return writeInternal(src, position);
   798             }
   838             }
   809             begin();
   849             begin();
   810             ti = threads.add();
   850             ti = threads.add();
   811             if (!isOpen())
   851             if (!isOpen())
   812                 return -1;
   852                 return -1;
   813             do {
   853             do {
   814                 n = IOUtil.write(fd, src, position, nd);
   854                 n = IOUtil.write(fd, src, position, direct, alignment, nd);
   815             } while ((n == IOStatus.INTERRUPTED) && isOpen());
   855             } while ((n == IOStatus.INTERRUPTED) && isOpen());
   816             return IOStatus.normalize(n);
   856             return IOStatus.normalize(n);
   817         } finally {
   857         } finally {
   818             threads.remove(ti);
   858             threads.remove(ti);
   819             end(n > 0);
   859             end(n > 0);