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();
}
}
}