< prev index next >

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

Print this page




  24  */
  25 
  26 package sun.nio.ch;
  27 
  28 import java.io.FileDescriptor;
  29 import java.io.IOException;
  30 import java.lang.ref.Cleaner.Cleanable;
  31 import java.nio.ByteBuffer;
  32 import java.nio.MappedByteBuffer;
  33 import java.nio.channels.ClosedByInterruptException;
  34 import java.nio.channels.ClosedChannelException;
  35 import java.nio.channels.FileChannel;
  36 import java.nio.channels.FileLock;
  37 import java.nio.channels.FileLockInterruptionException;
  38 import java.nio.channels.NonReadableChannelException;
  39 import java.nio.channels.NonWritableChannelException;
  40 import java.nio.channels.OverlappingFileLockException;
  41 import java.nio.channels.ReadableByteChannel;
  42 import java.nio.channels.SelectableChannel;
  43 import java.nio.channels.WritableByteChannel;





  44 import java.util.ArrayList;
  45 import java.util.List;
  46 
  47 import jdk.internal.misc.JavaIOFileDescriptorAccess;
  48 import jdk.internal.misc.JavaNioAccess;
  49 import jdk.internal.misc.SharedSecrets;
  50 import jdk.internal.ref.Cleaner;
  51 import jdk.internal.ref.CleanerFactory;
  52 import sun.security.action.GetPropertyAction;
  53 
  54 public class FileChannelImpl
  55     extends FileChannel
  56 {
  57     // Memory allocation size for mapping buffers
  58     private static final long allocationGranularity;
  59 
  60     // Access to FileDescriptor internals
  61     private static final JavaIOFileDescriptorAccess fdAccess =
  62         SharedSecrets.getJavaIOFileDescriptorAccess();
  63 


  70     // File access mode (immutable)
  71     private final boolean writable;
  72     private final boolean readable;
  73 
  74     // Required to prevent finalization of creating stream (immutable)
  75     private final Object parent;
  76 
  77     // The path of the referenced file
  78     // (null if the parent stream is created with a file descriptor)
  79     private final String path;
  80 
  81     // Thread-safe set of IDs of native threads, for signalling
  82     private final NativeThreadSet threads = new NativeThreadSet(2);
  83 
  84     // Lock for operations involving position and size
  85     private final Object positionLock = new Object();
  86 
  87     // Positional-read is not interruptible
  88     private volatile boolean uninterruptible;
  89 






  90     // Cleanable with an action which closes this channel's file descriptor
  91     private final Cleanable closer;
  92 
  93     private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
  94                             boolean writable, Object parent)
  95     {
  96         this.fd = fd;
  97         this.readable = readable;
  98         this.writable = writable;
  99         this.parent = parent;
 100         this.path = path;

 101         this.nd = new FileDispatcherImpl();







 102         // Register a cleaning action if and only if there is no parent
 103         // as the parent will take care of closing the file descriptor.
 104         this.closer= parent != null ? null :
 105             CleanerFactory.cleaner().register(this, () -> fdAccess.close(fd));
 106     }
 107 
 108     // Used by FileInputStream.getChannel(), FileOutputStream.getChannel
 109     // and RandomAccessFile.getChannel()
 110     public static FileChannel open(FileDescriptor fd, String path,
 111                                    boolean readable, boolean writable,
 112                                    Object parent)
 113     {
 114         return new FileChannelImpl(fd, path, readable, writable, parent);







 115     }
 116 
 117     private void ensureOpen() throws IOException {
 118         if (!isOpen())
 119             throw new ClosedChannelException();
 120     }
 121 
 122     public void setUninterruptible() {
 123         uninterruptible = true;
 124     }
 125 
 126     // -- Standard channel operations --
 127 
 128     protected void implCloseChannel() throws IOException {
 129         if (!fd.valid())
 130             return; // nothing to do
 131 
 132         // Release and invalidate any locks that we still hold
 133         if (fileLockTable != null) {
 134             for (FileLock fl: fileLockTable.removeAll()) {


 150             // will reinvoke our close method, which is defined in the
 151             // superclass AbstractInterruptibleChannel, but the isOpen logic in
 152             // that method will prevent this method from being reinvoked.
 153             //
 154             ((java.io.Closeable)parent).close();
 155         } else if (closer != null) {
 156             // Perform the cleaning action so it is not redone when
 157             // this channel becomes phantom reachable.
 158             closer.clean();
 159         } else {
 160             fdAccess.close(fd);
 161         }
 162 
 163     }
 164 
 165     public int read(ByteBuffer dst) throws IOException {
 166         ensureOpen();
 167         if (!readable)
 168             throw new NonReadableChannelException();
 169         synchronized (positionLock) {


 170             int n = 0;
 171             int ti = -1;
 172             try {
 173                 begin();
 174                 ti = threads.add();
 175                 if (!isOpen())
 176                     return 0;
 177                 do {
 178                     n = IOUtil.read(fd, dst, -1, nd);
 179                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 180                 return IOStatus.normalize(n);
 181             } finally {
 182                 threads.remove(ti);
 183                 end(n > 0);
 184                 assert IOStatus.check(n);
 185             }
 186         }
 187     }
 188 
 189     public long read(ByteBuffer[] dsts, int offset, int length)
 190         throws IOException
 191     {
 192         if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
 193             throw new IndexOutOfBoundsException();
 194         ensureOpen();
 195         if (!readable)
 196             throw new NonReadableChannelException();
 197         synchronized (positionLock) {


 198             long n = 0;
 199             int ti = -1;
 200             try {
 201                 begin();
 202                 ti = threads.add();
 203                 if (!isOpen())
 204                     return 0;
 205                 do {
 206                     n = IOUtil.read(fd, dsts, offset, length, nd);

 207                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 208                 return IOStatus.normalize(n);
 209             } finally {
 210                 threads.remove(ti);
 211                 end(n > 0);
 212                 assert IOStatus.check(n);
 213             }
 214         }
 215     }
 216 
 217     public int write(ByteBuffer src) throws IOException {
 218         ensureOpen();
 219         if (!writable)
 220             throw new NonWritableChannelException();
 221         synchronized (positionLock) {


 222             int n = 0;
 223             int ti = -1;
 224             try {
 225                 begin();
 226                 ti = threads.add();
 227                 if (!isOpen())
 228                     return 0;
 229                 do {
 230                     n = IOUtil.write(fd, src, -1, nd);
 231                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 232                 return IOStatus.normalize(n);
 233             } finally {
 234                 threads.remove(ti);
 235                 end(n > 0);
 236                 assert IOStatus.check(n);
 237             }
 238         }
 239     }
 240 
 241     public long write(ByteBuffer[] srcs, int offset, int length)
 242         throws IOException
 243     {
 244         if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
 245             throw new IndexOutOfBoundsException();
 246         ensureOpen();
 247         if (!writable)
 248             throw new NonWritableChannelException();
 249         synchronized (positionLock) {


 250             long n = 0;
 251             int ti = -1;
 252             try {
 253                 begin();
 254                 ti = threads.add();
 255                 if (!isOpen())
 256                     return 0;
 257                 do {
 258                     n = IOUtil.write(fd, srcs, offset, length, nd);

 259                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 260                 return IOStatus.normalize(n);
 261             } finally {
 262                 threads.remove(ti);
 263                 end(n > 0);
 264                 assert IOStatus.check(n);
 265             }
 266         }
 267     }
 268 
 269     // -- Other operations --
 270 
 271     public long position() throws IOException {
 272         ensureOpen();
 273         synchronized (positionLock) {
 274             long p = -1;
 275             int ti = -1;
 276             try {
 277                 begin();
 278                 ti = threads.add();


 721         if (!writable)
 722             throw new NonWritableChannelException();
 723         if ((position < 0) || (count < 0))
 724             throw new IllegalArgumentException();
 725         if (position > size())
 726             return 0;
 727         if (src instanceof FileChannelImpl)
 728            return transferFromFileChannel((FileChannelImpl)src,
 729                                           position, count);
 730 
 731         return transferFromArbitraryChannel(src, position, count);
 732     }
 733 
 734     public int read(ByteBuffer dst, long position) throws IOException {
 735         if (dst == null)
 736             throw new NullPointerException();
 737         if (position < 0)
 738             throw new IllegalArgumentException("Negative position");
 739         if (!readable)
 740             throw new NonReadableChannelException();


 741         ensureOpen();
 742         if (nd.needsPositionLock()) {
 743             synchronized (positionLock) {
 744                 return readInternal(dst, position);
 745             }
 746         } else {
 747             return readInternal(dst, position);
 748         }
 749     }
 750 
 751     private int readInternal(ByteBuffer dst, long position) throws IOException {
 752         assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
 753         int n = 0;
 754         int ti = -1;
 755 
 756         boolean interruptible = !uninterruptible;
 757         try {
 758             if (interruptible) begin();
 759             ti = threads.add();
 760             if (!isOpen())
 761                 return -1;
 762             do {
 763                 n = IOUtil.read(fd, dst, position, nd);
 764             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 765             return IOStatus.normalize(n);
 766         } finally {
 767             threads.remove(ti);
 768             if (interruptible) end(n > 0);
 769             assert IOStatus.check(n);
 770         }
 771     }
 772 
 773     public int write(ByteBuffer src, long position) throws IOException {
 774         if (src == null)
 775             throw new NullPointerException();
 776         if (position < 0)
 777             throw new IllegalArgumentException("Negative position");
 778         if (!writable)
 779             throw new NonWritableChannelException();


 780         ensureOpen();
 781         if (nd.needsPositionLock()) {
 782             synchronized (positionLock) {
 783                 return writeInternal(src, position);
 784             }
 785         } else {
 786             return writeInternal(src, position);
 787         }
 788     }
 789 
 790     private int writeInternal(ByteBuffer src, long position) throws IOException {
 791         assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
 792         int n = 0;
 793         int ti = -1;
 794         try {
 795             begin();
 796             ti = threads.add();
 797             if (!isOpen())
 798                 return -1;
 799             do {
 800                 n = IOUtil.write(fd, src, position, nd);
 801             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 802             return IOStatus.normalize(n);
 803         } finally {
 804             threads.remove(ti);
 805             end(n > 0);
 806             assert IOStatus.check(n);
 807         }
 808     }
 809 
 810 
 811     // -- Memory-mapped buffers --
 812 
 813     private static class Unmapper
 814         implements Runnable
 815     {
 816         // may be required to close file
 817         private static final NativeDispatcher nd = new FileDispatcherImpl();
 818 
 819         // keep track of mapped buffer usage
 820         static volatile int count;




  24  */
  25 
  26 package sun.nio.ch;
  27 
  28 import java.io.FileDescriptor;
  29 import java.io.IOException;
  30 import java.lang.ref.Cleaner.Cleanable;
  31 import java.nio.ByteBuffer;
  32 import java.nio.MappedByteBuffer;
  33 import java.nio.channels.ClosedByInterruptException;
  34 import java.nio.channels.ClosedChannelException;
  35 import java.nio.channels.FileChannel;
  36 import java.nio.channels.FileLock;
  37 import java.nio.channels.FileLockInterruptionException;
  38 import java.nio.channels.NonReadableChannelException;
  39 import java.nio.channels.NonWritableChannelException;
  40 import java.nio.channels.OverlappingFileLockException;
  41 import java.nio.channels.ReadableByteChannel;
  42 import java.nio.channels.SelectableChannel;
  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;
  49 import java.util.ArrayList;
  50 import java.util.List;
  51 
  52 import jdk.internal.misc.JavaIOFileDescriptorAccess;
  53 import jdk.internal.misc.JavaNioAccess;
  54 import jdk.internal.misc.SharedSecrets;
  55 import jdk.internal.ref.Cleaner;
  56 import jdk.internal.ref.CleanerFactory;
  57 import sun.security.action.GetPropertyAction;
  58 
  59 public class FileChannelImpl
  60     extends FileChannel
  61 {
  62     // Memory allocation size for mapping buffers
  63     private static final long allocationGranularity;
  64 
  65     // Access to FileDescriptor internals
  66     private static final JavaIOFileDescriptorAccess fdAccess =
  67         SharedSecrets.getJavaIOFileDescriptorAccess();
  68 


  75     // File access mode (immutable)
  76     private final boolean writable;
  77     private final boolean readable;
  78 
  79     // Required to prevent finalization of creating stream (immutable)
  80     private final Object parent;
  81 
  82     // The path of the referenced file
  83     // (null if the parent stream is created with a file descriptor)
  84     private final String path;
  85 
  86     // Thread-safe set of IDs of native threads, for signalling
  87     private final NativeThreadSet threads = new NativeThreadSet(2);
  88 
  89     // Lock for operations involving position and size
  90     private final Object positionLock = new Object();
  91 
  92     // Positional-read is not interruptible
  93     private volatile boolean uninterruptible;
  94 
  95     // DirectIO flag
  96     private final boolean direct;
  97 
  98     // IO alignment value for DirectIO
  99     private final int alignment;
 100 
 101     // Cleanable with an action which closes this channel's file descriptor
 102     private final Cleanable closer;
 103 
 104     private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
 105                             boolean writable, boolean direct, Object parent)
 106     {
 107         this.fd = fd;
 108         this.readable = readable;
 109         this.writable = writable;
 110         this.parent = parent;
 111         this.path = path;
 112         this.direct = direct;
 113         this.nd = new FileDispatcherImpl();
 114         if (direct) {
 115             assert path != null;
 116             this.alignment = nd.setDirectIO(fd, path);
 117         } else {
 118             this.alignment = -1;
 119         }
 120 
 121         // Register a cleaning action if and only if there is no parent
 122         // as the parent will take care of closing the file descriptor.
 123         this.closer= parent != null ? null :
 124             CleanerFactory.cleaner().register(this, () -> fdAccess.close(fd));
 125     }
 126 
 127     // Used by FileInputStream.getChannel(), FileOutputStream.getChannel
 128     // and RandomAccessFile.getChannel()
 129     public static FileChannel open(FileDescriptor fd, String path,
 130                                    boolean readable, boolean writable,
 131                                    Object parent)
 132     {
 133         return new FileChannelImpl(fd, path, readable, writable, false, parent);
 134     }
 135 
 136     public static FileChannel open(FileDescriptor fd, String path,
 137                                    boolean readable, boolean writable,
 138                                    boolean direct, Object parent)
 139     {
 140         return new FileChannelImpl(fd, path, readable, writable, direct, parent);
 141     }
 142 
 143     private void ensureOpen() throws IOException {
 144         if (!isOpen())
 145             throw new ClosedChannelException();
 146     }
 147 
 148     public void setUninterruptible() {
 149         uninterruptible = true;
 150     }
 151 
 152     // -- Standard channel operations --
 153 
 154     protected void implCloseChannel() throws IOException {
 155         if (!fd.valid())
 156             return; // nothing to do
 157 
 158         // Release and invalidate any locks that we still hold
 159         if (fileLockTable != null) {
 160             for (FileLock fl: fileLockTable.removeAll()) {


 176             // will reinvoke our close method, which is defined in the
 177             // superclass AbstractInterruptibleChannel, but the isOpen logic in
 178             // that method will prevent this method from being reinvoked.
 179             //
 180             ((java.io.Closeable)parent).close();
 181         } else if (closer != null) {
 182             // Perform the cleaning action so it is not redone when
 183             // this channel becomes phantom reachable.
 184             closer.clean();
 185         } else {
 186             fdAccess.close(fd);
 187         }
 188 
 189     }
 190 
 191     public int read(ByteBuffer dst) throws IOException {
 192         ensureOpen();
 193         if (!readable)
 194             throw new NonReadableChannelException();
 195         synchronized (positionLock) {
 196             if (direct)
 197                 Util.checkChannelPositionAligned(position(), alignment);
 198             int n = 0;
 199             int ti = -1;
 200             try {
 201                 begin();
 202                 ti = threads.add();
 203                 if (!isOpen())
 204                     return 0;
 205                 do {
 206                     n = IOUtil.read(fd, dst, -1, direct, alignment, nd);
 207                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 208                 return IOStatus.normalize(n);
 209             } finally {
 210                 threads.remove(ti);
 211                 end(n > 0);
 212                 assert IOStatus.check(n);
 213             }
 214         }
 215     }
 216 
 217     public long read(ByteBuffer[] dsts, int offset, int length)
 218         throws IOException
 219     {
 220         if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
 221             throw new IndexOutOfBoundsException();
 222         ensureOpen();
 223         if (!readable)
 224             throw new NonReadableChannelException();
 225         synchronized (positionLock) {
 226             if (direct)
 227                 Util.checkChannelPositionAligned(position(), alignment);
 228             long n = 0;
 229             int ti = -1;
 230             try {
 231                 begin();
 232                 ti = threads.add();
 233                 if (!isOpen())
 234                     return 0;
 235                 do {
 236                     n = IOUtil.read(fd, dsts, offset, length,
 237                             direct, alignment, nd);
 238                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 239                 return IOStatus.normalize(n);
 240             } finally {
 241                 threads.remove(ti);
 242                 end(n > 0);
 243                 assert IOStatus.check(n);
 244             }
 245         }
 246     }
 247 
 248     public int write(ByteBuffer src) throws IOException {
 249         ensureOpen();
 250         if (!writable)
 251             throw new NonWritableChannelException();
 252         synchronized (positionLock) {
 253             if (direct)
 254                 Util.checkChannelPositionAligned(position(), alignment);
 255             int n = 0;
 256             int ti = -1;
 257             try {
 258                 begin();
 259                 ti = threads.add();
 260                 if (!isOpen())
 261                     return 0;
 262                 do {
 263                     n = IOUtil.write(fd, src, -1, direct, alignment, nd);
 264                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 265                 return IOStatus.normalize(n);
 266             } finally {
 267                 threads.remove(ti);
 268                 end(n > 0);
 269                 assert IOStatus.check(n);
 270             }
 271         }
 272     }
 273 
 274     public long write(ByteBuffer[] srcs, int offset, int length)
 275         throws IOException
 276     {
 277         if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
 278             throw new IndexOutOfBoundsException();
 279         ensureOpen();
 280         if (!writable)
 281             throw new NonWritableChannelException();
 282         synchronized (positionLock) {
 283             if (direct)
 284                 Util.checkChannelPositionAligned(position(), alignment);
 285             long n = 0;
 286             int ti = -1;
 287             try {
 288                 begin();
 289                 ti = threads.add();
 290                 if (!isOpen())
 291                     return 0;
 292                 do {
 293                     n = IOUtil.write(fd, srcs, offset, length,
 294                             direct, alignment, nd);
 295                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 296                 return IOStatus.normalize(n);
 297             } finally {
 298                 threads.remove(ti);
 299                 end(n > 0);
 300                 assert IOStatus.check(n);
 301             }
 302         }
 303     }
 304 
 305     // -- Other operations --
 306 
 307     public long position() throws IOException {
 308         ensureOpen();
 309         synchronized (positionLock) {
 310             long p = -1;
 311             int ti = -1;
 312             try {
 313                 begin();
 314                 ti = threads.add();


 757         if (!writable)
 758             throw new NonWritableChannelException();
 759         if ((position < 0) || (count < 0))
 760             throw new IllegalArgumentException();
 761         if (position > size())
 762             return 0;
 763         if (src instanceof FileChannelImpl)
 764            return transferFromFileChannel((FileChannelImpl)src,
 765                                           position, count);
 766 
 767         return transferFromArbitraryChannel(src, position, count);
 768     }
 769 
 770     public int read(ByteBuffer dst, long position) throws IOException {
 771         if (dst == null)
 772             throw new NullPointerException();
 773         if (position < 0)
 774             throw new IllegalArgumentException("Negative position");
 775         if (!readable)
 776             throw new NonReadableChannelException();
 777         if (direct)
 778             Util.checkChannelPositionAligned(position, alignment);
 779         ensureOpen();
 780         if (nd.needsPositionLock()) {
 781             synchronized (positionLock) {
 782                 return readInternal(dst, position);
 783             }
 784         } else {
 785             return readInternal(dst, position);
 786         }
 787     }
 788 
 789     private int readInternal(ByteBuffer dst, long position) throws IOException {
 790         assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
 791         int n = 0;
 792         int ti = -1;
 793 
 794         boolean interruptible = !uninterruptible;
 795         try {
 796             if (interruptible) begin();
 797             ti = threads.add();
 798             if (!isOpen())
 799                 return -1;
 800             do {
 801                 n = IOUtil.read(fd, dst, position, direct, alignment, nd);
 802             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 803             return IOStatus.normalize(n);
 804         } finally {
 805             threads.remove(ti);
 806             if (interruptible) end(n > 0);
 807             assert IOStatus.check(n);
 808         }
 809     }
 810 
 811     public int write(ByteBuffer src, long position) throws IOException {
 812         if (src == null)
 813             throw new NullPointerException();
 814         if (position < 0)
 815             throw new IllegalArgumentException("Negative position");
 816         if (!writable)
 817             throw new NonWritableChannelException();
 818         if (direct)
 819             Util.checkChannelPositionAligned(position, alignment);
 820         ensureOpen();
 821         if (nd.needsPositionLock()) {
 822             synchronized (positionLock) {
 823                 return writeInternal(src, position);
 824             }
 825         } else {
 826             return writeInternal(src, position);
 827         }
 828     }
 829 
 830     private int writeInternal(ByteBuffer src, long position) throws IOException {
 831         assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
 832         int n = 0;
 833         int ti = -1;
 834         try {
 835             begin();
 836             ti = threads.add();
 837             if (!isOpen())
 838                 return -1;
 839             do {
 840                 n = IOUtil.write(fd, src, position, direct, alignment, nd);
 841             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 842             return IOStatus.normalize(n);
 843         } finally {
 844             threads.remove(ti);
 845             end(n > 0);
 846             assert IOStatus.check(n);
 847         }
 848     }
 849 
 850 
 851     // -- Memory-mapped buffers --
 852 
 853     private static class Unmapper
 854         implements Runnable
 855     {
 856         // may be required to close file
 857         private static final NativeDispatcher nd = new FileDispatcherImpl();
 858 
 859         // keep track of mapped buffer usage
 860         static volatile int count;


< prev index next >