HBASE-25691 Test failure: TestVerifyBucketCacheFile.testRetrieveFromFile (#3081)

The issue is that FileInputStream is created with try-with-resources, so its close() is called right after the try sentence.
FileInputStream is a finalize class, when this object is garbage collected, its close() is called again.
To avoid this double-free resources, add guard against it.

Signed-off-by: stack <stack@apache.org>
This commit is contained in:
huaxiangsun 2021-03-24 09:01:17 -07:00 committed by GitHub
parent 202b17f4fc
commit 1e3fe3ceac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 17 additions and 4 deletions

View File

@ -1112,14 +1112,27 @@ public class BucketCache implements BlockCache, HeapSize {
*/ */
private FileInputStream deleteFileOnClose(final File file) throws IOException { private FileInputStream deleteFileOnClose(final File file) throws IOException {
return new FileInputStream(file) { return new FileInputStream(file) {
private File myFile;
private FileInputStream init(File file) {
myFile = file;
return this;
}
@Override @Override
public void close() throws IOException { public void close() throws IOException {
// close() will be called during try-with-resources and it will be
// called by finalizer thread during GC. To avoid double-free resource,
// set myFile to null after the first call.
if (myFile == null) {
return;
}
super.close(); super.close();
if (!file.delete()) { if (!myFile.delete()) {
throw new IOException("Failed deleting persistence file " + file.getAbsolutePath()); throw new IOException("Failed deleting persistence file " + myFile.getAbsolutePath());
} }
myFile = null;
} }
}; }.init(file);
} }
private void verifyCapacityAndClasses(long capacitySize, String ioclass, String mapclass) private void verifyCapacityAndClasses(long capacitySize, String ioclass, String mapclass)