src/solaris/classes/java/io/FileDescriptor.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 23,33 ****
* 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
--- 23,34 ----
* 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
*** 44,72 ****
*/
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
--- 45,68 ----
*/
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
*** 162,176 ****
}
}
);
}
! // package private methods used by FIS, FOS and RAF
! int incrementAndGetUseCount() {
! return useCount.incrementAndGet();
}
! int decrementAndGetUseCount() {
! return useCount.decrementAndGet();
}
}
--- 158,226 ----
}
}
);
}
! /*
! * 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;
+ }
+ }
+ }
}