src/solaris/classes/java/io/FileDescriptor.java

Print this page

        

*** 22,34 **** * or visit www.oracle.com if you need additional information or have any * questions. */ package java.io; - import java.util.ArrayList; - import java.util.List; /** * Instances of the file descriptor class serve as an opaque handle * to the underlying machine-specific structure representing an open * file, an open socket, or another source or sink of bytes. The * main practical use for a file descriptor is to create a --- 22,34 ---- * or visit www.oracle.com if you need additional information or have any * questions. */ package java.io; + import java.util.concurrent.atomic.AtomicInteger; + /** * Instances of the file descriptor class serve as an opaque handle * to the underlying machine-specific structure representing an open * file, an open socket, or another source or sink of bytes. The * main practical use for a file descriptor is to create a
*** 43,66 **** * @since JDK1.0 */ public final class FileDescriptor { private int fd; - private Closeable parent; - private List<Closeable> otherParents; - private boolean closed; /** * Constructs an (invalid) FileDescriptor * object. */ public /**/ FileDescriptor() { fd = -1; } private /* */ FileDescriptor(int fd) { this.fd = fd; } /** * A handle to the standard input stream. Usually, this file * descriptor is not used directly, but rather via the input stream --- 43,72 ---- * @since JDK1.0 */ public final class FileDescriptor { private int fd; /** + * A counter for tracking the FIS/FOS/RAF instances that + * use this FileDescriptor. The FIS/FOS.finalize() will not release + * the FileDescriptor if it is still under user by a stream. + */ + private AtomicInteger useCount; + + /** * Constructs an (invalid) FileDescriptor * object. */ public /**/ FileDescriptor() { fd = -1; + useCount = new AtomicInteger(); } private /* */ FileDescriptor(int fd) { this.fd = fd; + useCount = new AtomicInteger(); } /** * A handle to the standard input stream. Usually, this file * descriptor is not used directly, but rather via the input stream
*** 156,224 **** } } ); } ! /* ! * Package private methods to track referents. ! * If multiple streams point to the same FileDescriptor, we cycle ! * through the list of all referents and call close() ! */ ! /** ! * Attach a Closeable to this FD for tracking. ! * parent reference is added to otherParents when ! * needed to make closeAll simpler. ! */ ! synchronized void attach(Closeable c) { ! if (parent == null) { ! // first caller gets to do this ! parent = c; ! } else if (otherParents == null) { ! otherParents = new ArrayList<>(); ! otherParents.add(parent); ! otherParents.add(c); ! } else { ! otherParents.add(c); } - } ! /** ! * Cycle through all Closeables sharing this FD and call ! * close() on each one. ! * ! * The caller closeable gets to call close0(). ! */ ! @SuppressWarnings("try") ! synchronized void closeAll(Closeable releaser) throws IOException { ! if (!closed) { ! closed = true; ! IOException ioe = null; ! try (Closeable c = releaser) { ! if (otherParents != null) { ! for (Closeable referent : otherParents) { ! try { ! referent.close(); ! } catch(IOException x) { ! if (ioe == null) { ! ioe = x; ! } else { ! ioe.addSuppressed(x); } - } - } - } - } catch(IOException ex) { - /* - * If releaser close() throws IOException - * add other exceptions as suppressed. - */ - if (ioe != null) - ex.addSuppressed(ioe); - ioe = ex; - } finally { - if (ioe != null) - throw ioe; - } - } - } } --- 162,176 ---- } } ); } ! // package private methods used by FIS, FOS and RAF ! int incrementAndGetUseCount() { ! return useCount.incrementAndGet(); } ! int decrementAndGetUseCount() { ! return useCount.decrementAndGet(); } }