This is an automated email from the ASF dual-hosted git repository.

huaxiangsun pushed a commit to branch branch-2.4
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.4 by this push:
     new 91205bf  HBASE-25691 Test failure: 
TestVerifyBucketCacheFile.testRetrieveFromFile (#3088)
91205bf is described below

commit 91205bf227e8d5df21e34cd257514886f9a18365
Author: huaxiangsun <huaxiang...@apache.org>
AuthorDate: Wed Mar 24 14:39:35 2021 -0700

    HBASE-25691 Test failure: TestVerifyBucketCacheFile.testRetrieveFromFile 
(#3088)
    
    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 <st...@apache.org>
---
 .../hadoop/hbase/io/hfile/bucket/BucketCache.java     | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
index de44ad7..1f9aac4 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
@@ -1101,14 +1101,27 @@ public class BucketCache implements BlockCache, 
HeapSize {
    */
   private FileInputStream deleteFileOnClose(final File file) throws 
IOException {
     return new FileInputStream(file) {
+      private File myFile;
+      private FileInputStream init(File file) {
+        myFile = file;
+        return this;
+      }
       @Override
       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();
-        if (!file.delete()) {
-          throw new IOException("Failed deleting persistence file " + 
file.getAbsolutePath());
+        if (!myFile.delete()) {
+          throw new IOException("Failed deleting persistence file " + 
myFile.getAbsolutePath());
         }
+        myFile = null;
       }
-    };
+    }.init(file);
   }
 
   private void verifyCapacityAndClasses(long capacitySize, String ioclass, 
String mapclass)

Reply via email to