< prev index next >
test/jdk/java/io/FileInputStream/UnreferencedFISClosesFd.java
Print this page
rev 52044 : 8192939: Remove Finalize methods from FileInputStream and FileOutputStream
*** 60,78 ****
* - Subclasses finalize overridden - cleaner cleanup
* - Subclasses finalize and close overridden - AltFinalizer cleanup
*/
public class UnreferencedFISClosesFd {
- enum CleanupType {
- CLOSE, // Cleanup is handled via calling close
- CLEANER} // Cleanup is handled via Cleaner
-
static final String FILE_NAME = "empty.txt";
/**
* Subclass w/ no overrides; not finalize or close.
! * Cleanup should be via the Cleaner (not close).
*/
public static class StreamOverrides extends FileInputStream {
protected final AtomicInteger closeCounter;
--- 60,74 ----
* - Subclasses finalize overridden - cleaner cleanup
* - Subclasses finalize and close overridden - AltFinalizer cleanup
*/
public class UnreferencedFISClosesFd {
static final String FILE_NAME = "empty.txt";
/**
* Subclass w/ no overrides; not finalize or close.
! * Cleanup should be via the Cleaner.
*/
public static class StreamOverrides extends FileInputStream {
protected final AtomicInteger closeCounter;
*** 86,96 ****
}
}
/**
* Subclass overrides close.
! * Cleanup should be via AltFinalizer calling close().
*/
public static class StreamOverridesClose extends StreamOverrides {
public StreamOverridesClose(String name) throws FileNotFoundException {
super(name);
--- 82,92 ----
}
}
/**
* Subclass overrides close.
! * Cleanup should be via the Cleaner.
*/
public static class StreamOverridesClose extends StreamOverrides {
public StreamOverridesClose(String name) throws FileNotFoundException {
super(name);
*** 102,121 ****
}
}
/**
* Subclass overrides finalize.
! * Cleanup should be via the Cleaner (not close).
*/
public static class StreamOverridesFinalize extends StreamOverrides {
public StreamOverridesFinalize(String name) throws FileNotFoundException {
super(name);
}
@SuppressWarnings({"deprecation","removal"})
! protected void finalize() throws IOException {
super.finalize();
}
}
/**
--- 98,117 ----
}
}
/**
* Subclass overrides finalize.
! * Cleanup should be via the Cleaner.
*/
public static class StreamOverridesFinalize extends StreamOverrides {
public StreamOverridesFinalize(String name) throws FileNotFoundException {
super(name);
}
@SuppressWarnings({"deprecation","removal"})
! protected void finalize() throws IOException, Throwable {
super.finalize();
}
}
/**
*** 127,137 ****
public StreamOverridesFinalizeClose(String name) throws FileNotFoundException {
super(name);
}
@SuppressWarnings({"deprecation","removal"})
! protected void finalize() throws IOException {
super.finalize();
}
}
/**
--- 123,133 ----
public StreamOverridesFinalizeClose(String name) throws FileNotFoundException {
super(name);
}
@SuppressWarnings({"deprecation","removal"})
! protected void finalize() throws IOException, Throwable {
super.finalize();
}
}
/**
*** 147,165 ****
FileUtils.listFileDescriptors(System.out);
long fdCount0 = getFdCount();
int failCount = 0;
! failCount += test(new FileInputStream(name), CleanupType.CLEANER);
! failCount += test(new StreamOverrides(name), CleanupType.CLEANER);
! failCount += test(new StreamOverridesClose(name), CleanupType.CLOSE);
! failCount += test(new StreamOverridesFinalize(name), CleanupType.CLEANER);
! failCount += test(new StreamOverridesFinalizeClose(name), CleanupType.CLOSE);
if (failCount > 0) {
throw new AssertionError("Failed test count: " + failCount);
}
--- 143,161 ----
FileUtils.listFileDescriptors(System.out);
long fdCount0 = getFdCount();
int failCount = 0;
! failCount += test(new FileInputStream(name));
! failCount += test(new StreamOverrides(name));
! failCount += test(new StreamOverridesClose(name));
! failCount += test(new StreamOverridesFinalize(name));
! failCount += test(new StreamOverridesFinalizeClose(name));
if (failCount > 0) {
throw new AssertionError("Failed test count: " + failCount);
}
*** 178,188 ****
return (mxBean instanceof UnixOperatingSystemMXBean)
? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
: -1L;
}
! private static int test(FileInputStream fis, CleanupType cleanType) throws Exception {
try {
System.out.printf("%nTesting %s%n", fis.getClass().getName());
// Prepare to wait for FIS to be reclaimed
--- 174,184 ----
return (mxBean instanceof UnixOperatingSystemMXBean)
? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
: -1L;
}
! private static int test(FileInputStream fis) throws Exception {
try {
System.out.printf("%nTesting %s%n", fis.getClass().getName());
// Prepare to wait for FIS to be reclaimed
*** 197,235 ****
Field fdField = FileDescriptor.class.getDeclaredField("fd");
fdField.setAccessible(true);
int ffd = fdField.getInt(fd);
- Field altFinalizerField = FileInputStream.class.getDeclaredField("altFinalizer");
- altFinalizerField.setAccessible(true);
- Object altFinalizer = altFinalizerField.get(fis);
- if ((altFinalizer != null) ^ (cleanType == CleanupType.CLOSE)) {
- throw new RuntimeException("Unexpected AltFinalizer: " + altFinalizer
- + ", for " + cleanType);
- }
-
Field cleanupField = FileDescriptor.class.getDeclaredField("cleanup");
cleanupField.setAccessible(true);
Object cleanup = cleanupField.get(fd);
! System.out.printf(" cleanup: %s, alt: %s, ffd: %d, cf: %s%n",
! cleanup, altFinalizer, ffd, cleanupField);
! if ((cleanup != null) ^ (cleanType == CleanupType.CLEANER)) {
! throw new Exception("unexpected cleanup: "
! + cleanup + ", for " + cleanType);
}
! if (cleanup != null) {
WeakReference<Object> cleanupWeak = new WeakReference<>(cleanup, queue);
pending.add(cleanupWeak);
System.out.printf(" fdWeak: %s%n msWeak: %s%n cleanupWeak: %s%n",
fdWeak, msWeak, cleanupWeak);
- }
- if (altFinalizer != null) {
- WeakReference<Object> altFinalizerWeak = new WeakReference<>(altFinalizer, queue);
- pending.add(altFinalizerWeak);
- System.out.printf(" fdWeak: %s%n msWeak: %s%n altFinalizerWeak: %s%n",
- fdWeak, msWeak, altFinalizerWeak);
- }
AtomicInteger closeCounter = fis instanceof StreamOverrides
? ((StreamOverrides)fis).closeCounter() : null;
Reference<?> r;
--- 193,214 ----
Field fdField = FileDescriptor.class.getDeclaredField("fd");
fdField.setAccessible(true);
int ffd = fdField.getInt(fd);
Field cleanupField = FileDescriptor.class.getDeclaredField("cleanup");
cleanupField.setAccessible(true);
Object cleanup = cleanupField.get(fd);
! System.out.printf(" cleanup: %s, ffd: %d, cf: %s%n", cleanup, ffd, cleanupField);
! if (cleanup == null) {
! throw new RuntimeException("cleanup should not be null");
}
!
WeakReference<Object> cleanupWeak = new WeakReference<>(cleanup, queue);
pending.add(cleanupWeak);
System.out.printf(" fdWeak: %s%n msWeak: %s%n cleanupWeak: %s%n",
fdWeak, msWeak, cleanupWeak);
AtomicInteger closeCounter = fis instanceof StreamOverrides
? ((StreamOverrides)fis).closeCounter() : null;
Reference<?> r;
*** 241,272 ****
pending.remove(r);
} else {
fis = null;
fd = null;
cleanup = null;
- altFinalizer = null;
System.gc(); // attempt to reclaim them
}
}
Reference.reachabilityFence(fd);
Reference.reachabilityFence(fis);
Reference.reachabilityFence(cleanup);
- Reference.reachabilityFence(altFinalizer);
// Confirm the correct number of calls to close depending on the cleanup type
- switch (cleanType) {
- case CLEANER:
if (closeCounter != null && closeCounter.get() > 0) {
! throw new RuntimeException("Close should not have been called: count: "
! + closeCounter);
! }
! break;
! case CLOSE:
! if (closeCounter == null || closeCounter.get() == 0) {
! throw new RuntimeException("Close should have been called: count: 0");
! }
! break;
}
} catch (Exception ex) {
ex.printStackTrace(System.out);
return 1;
}
--- 220,239 ----
pending.remove(r);
} else {
fis = null;
fd = null;
cleanup = null;
System.gc(); // attempt to reclaim them
}
}
Reference.reachabilityFence(fd);
Reference.reachabilityFence(fis);
Reference.reachabilityFence(cleanup);
// Confirm the correct number of calls to close depending on the cleanup type
if (closeCounter != null && closeCounter.get() > 0) {
! throw new RuntimeException("Close should not have been called: count: " + closeCounter);
}
} catch (Exception ex) {
ex.printStackTrace(System.out);
return 1;
}
< prev index next >