src/windows/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
*** 40,61 **** * @since JDK1.0 */ public final class FileDescriptor { private int fd; private long handle; - private Closeable parent; - private List<Closeable> otherParents; - private boolean closed; /** * Constructs an (invalid) FileDescriptor * object. */ public /**/ FileDescriptor() { fd = -1; handle = -1; } static { initIDs(); } --- 40,68 ---- * @since JDK1.0 */ public final class FileDescriptor { private int fd; + private long handle; /** + * A use 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 use by any stream. + */ + private AtomicInteger useCount; + + + /** * Constructs an (invalid) FileDescriptor * object. */ public /**/ FileDescriptor() { fd = -1; handle = -1; + useCount = new AtomicInteger(); } static { initIDs(); }
*** 159,227 **** FileDescriptor desc = new FileDescriptor(); desc.handle = set(fd); return desc; } ! /* ! * 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; - } - } - } } --- 166,180 ---- FileDescriptor desc = new FileDescriptor(); desc.handle = set(fd); return desc; } ! // package private methods used by FIS, FOS and RAF. ! int incrementAndGetUseCount() { ! return useCount.incrementAndGet(); } ! int decrementAndGetUseCount() { ! return useCount.decrementAndGet(); } }