src/windows/classes/java/io/FileDescriptor.java
Print this page
@@ -22,13 +22,13 @@
* 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;
+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,22 +40,29 @@
* @since JDK1.0
*/
public final class FileDescriptor {
private int fd;
+
private long handle;
- private Closeable parent;
- private List<Closeable> otherParents;
- private boolean closed;
/**
+ * 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,69 +166,15 @@
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()
- */
+ // package private methods used by FIS, FOS and RAF.
- /**
- * 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);
+ int incrementAndGetUseCount() {
+ return useCount.incrementAndGet();
}
- }
- /**
- * 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);
+ int decrementAndGetUseCount() {
+ return useCount.decrementAndGet();
}
- }
- }
- }
- } 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;
- }
- }
- }
}