src/share/classes/java/io/FileOutputStream.java

Print this page

        

*** 195,207 **** } if (name == null) { throw new NullPointerException(); } this.fd = new FileDescriptor(); this.append = append; - fd.incrementAndGetUseCount(); open(name, append); } /** * Creates a file output stream to write to the specified file --- 195,207 ---- } if (name == null) { throw new NullPointerException(); } this.fd = new FileDescriptor(); + fd.attach(this); this.append = append; open(name, append); } /** * Creates a file output stream to write to the specified file
*** 235,250 **** security.checkWrite(fdObj); } this.fd = fdObj; this.append = false; ! /* ! * FileDescriptor is being shared by streams. ! * Ensure that it's GC'ed only when all the streams/channels are done ! * using it. ! */ ! fd.incrementAndGetUseCount(); } /** * Opens a file, with the specified name, for overwriting or appending. * @param name name of file to be opened --- 235,245 ---- security.checkWrite(fdObj); } this.fd = fdObj; this.append = false; ! fd.attach(this); } /** * Opens a file, with the specified name, for overwriting or appending. * @param name name of file to be opened
*** 329,359 **** } closed = true; } if (channel != null) { - /* - * Decrement FD use count associated with the channel - * The use count is incremented whenever a new channel - * is obtained from this stream. - */ - fd.decrementAndGetUseCount(); channel.close(); } ! /* ! * Decrement FD use count associated with this stream ! */ ! int useCount = fd.decrementAndGetUseCount(); ! ! /* ! * If FileDescriptor is still in use by another stream, we ! * will not close it. ! */ ! if (useCount <= 0) { close0(); } } /** * Returns the file descriptor associated with this stream. * --- 324,341 ---- } closed = true; } if (channel != null) { channel.close(); } ! fd.closeAll(new Closeable() { ! public void close() throws IOException { close0(); } + }); } /** * Returns the file descriptor associated with this stream. *
*** 363,373 **** * * @exception IOException if an I/O error occurs. * @see java.io.FileDescriptor */ public final FileDescriptor getFD() throws IOException { ! if (fd != null) return fd; throw new IOException(); } /** * Returns the unique {@link java.nio.channels.FileChannel FileChannel} --- 345,357 ---- * * @exception IOException if an I/O error occurs. * @see java.io.FileDescriptor */ public final FileDescriptor getFD() throws IOException { ! if (fd != null) { ! return fd; ! } throw new IOException(); } /** * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
*** 388,404 **** */ public FileChannel getChannel() { synchronized (this) { if (channel == null) { channel = FileChannelImpl.open(fd, false, true, append, this); - - /* - * Increment fd's use count. Invoking the channel's close() - * method will result in decrementing the use count set for - * the channel. - */ - fd.incrementAndGetUseCount(); } return channel; } } --- 372,381 ----
*** 413,422 **** --- 390,404 ---- protected void finalize() throws IOException { if (fd != null) { if (fd == FileDescriptor.out || fd == FileDescriptor.err) { flush(); } else { + /* if fd is shared, the references in FileDescriptor + * will ensure that finalizer is only called when + * safe to do so. All references using the fd have + * become unreachable. We can call close() + */ close(); } } }