--- old/src/share/classes/java/io/FileInputStream.java Fri Nov 4 12:23:14 2011 +++ new/src/share/classes/java/io/FileInputStream.java Fri Nov 4 12:23:13 2011 @@ -124,7 +124,7 @@ throw new NullPointerException(); } fd = new FileDescriptor(); - fd.incrementAndGetUseCount(); + fd.attach(this); open(name); } @@ -164,10 +164,9 @@ /* * FileDescriptor is being shared by streams. - * Ensure that it's GC'ed only when all the streams/channels are done - * using it. + * Register this stream with FileDescriptor tracker. */ - fd.incrementAndGetUseCount(); + fd.attach(this); } /** @@ -294,29 +293,16 @@ closed = true; } if (channel != null) { - /* - * Decrement the 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 the FD use count associated with this stream - */ - int useCount = fd.decrementAndGetUseCount(); + fd.closeAll(new Closeable() { + public void close() throws IOException { + close0(); + } + }); + } - /* - * If FileDescriptor is still in use by another stream, we - * will not close it. - */ - if (useCount <= 0) { - close0(); - } - } - /** * Returns the FileDescriptor * object that represents the connection to @@ -328,7 +314,9 @@ * @see java.io.FileDescriptor */ public final FileDescriptor getFD() throws IOException { - if (fd != null) return fd; + if (fd != null) { + return fd; + } throw new IOException(); } @@ -352,18 +340,11 @@ synchronized (this) { if (channel == null) { channel = FileChannelImpl.open(fd, true, false, 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; } } - + private static native void initIDs(); private native void close0() throws IOException; @@ -381,7 +362,12 @@ */ protected void finalize() throws IOException { if ((fd != null) && (fd != FileDescriptor.in)) { - close(); + /* 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(); } } }