src/java.base/share/classes/java/io/FileInputStream.java

Print this page
rev 11066 : 8025619: (fc) FileInputStream.getChannel on closed stream returns FileChannel that doesn't know that stream is closed
Summary: FileKey.create() should throw an IOException directly instead of wrapping it in an Error.
Reviewed-by: TBD
rev 11067 : 8025619.01

@@ -24,10 +24,11 @@
  */
 
 package java.io;
 
 import java.nio.channels.FileChannel;
+import java.util.concurrent.atomic.AtomicBoolean;
 import sun.nio.ch.FileChannelImpl;
 
 
 /**
  * A <code>FileInputStream</code> obtains input bytes

@@ -57,12 +58,11 @@
      */
     private final String path;
 
     private FileChannel channel = null;
 
-    private final Object closeLock = new Object();
-    private volatile boolean closed = false;
+    private AtomicBoolean closed = new AtomicBoolean(false);
 
     /**
      * Creates a <code>FileInputStream</code> by
      * opening a connection to an actual file,
      * the file named by the path name <code>name</code>

@@ -311,16 +311,15 @@
      *
      * @revised 1.4
      * @spec JSR-51
      */
     public void close() throws IOException {
-        synchronized (closeLock) {
-            if (closed) {
+        if (!closed.compareAndSet(false, true)) {
+            // if compareAndSet() returns false closed was already true
                 return;
             }
-            closed = true;
-        }
+
         if (channel != null) {
            channel.close();
         }
 
         fd.closeAll(new Closeable() {

@@ -365,10 +364,17 @@
      */
     public FileChannel getChannel() {
         synchronized (this) {
             if (channel == null) {
                 channel = FileChannelImpl.open(fd, path, true, false, this);
+                if (closed.get()) {
+                    try {
+                        channel.close();
+                    } catch (IOException ioe) {
+                        throw new InternalError(ioe); // should not happen
+                    }
+                }
             }
             return channel;
         }
     }