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