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

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git

commit 6daaa2c037bb6db1f092dbd4565610ccee735237
Author: Murtadha Hubail <[email protected]>
AuthorDate: Fri Dec 14 16:34:38 2018 +0300

    [ASTERIXDB-2494][RT] Ensure Dataset Ref Counters Are Thread-safe
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    - Dataset/Index reference counters are modified concurrently by
      multiple threads and should be thread-safe. Thread-safety issues
      in these counters could result in leaving a dataset allocated
      in memory even though it can be evicted.
    
    Change-Id: I9328df660f463bd45bfc003b1e44c9df2702cc90
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/3089
    Sonar-Qube: Jenkins <[email protected]>
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Till Westmann <[email protected]>
---
 .../java/org/apache/asterix/common/context/DatasetInfo.java |  5 +++--
 .../asterix/common/context/DatasetLifecycleManager.java     |  8 +++++---
 .../main/java/org/apache/asterix/common/context/Info.java   | 13 +++++++------
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetInfo.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetInfo.java
index 6e2e320..4ccb0cc 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetInfo.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetInfo.java
@@ -18,6 +18,7 @@
  */
 package org.apache.asterix.common.context;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -159,8 +160,8 @@ public class DatasetInfo extends Info implements 
Comparable<DatasetInfo> {
         this.isExternal = isExternal;
     }
 
-    public Map<Long, IndexInfo> getIndexes() {
-        return indexes;
+    public synchronized Map<Long, IndexInfo> getIndexes() {
+        return Collections.unmodifiableMap(indexes);
     }
 
     public synchronized void addIndex(long resourceID, IndexInfo indexInfo) {
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
index 1dff69d..d767219 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/DatasetLifecycleManager.java
@@ -163,9 +163,11 @@ public class DatasetLifecycleManager implements 
IDatasetLifecycleManager, ILifeC
         dsInfo.waitForIO();
         closeIndex(iInfo);
         dsInfo.removeIndex(resourceID);
-        if (dsInfo.getReferenceCount() == 0 && dsInfo.isOpen() && 
dsInfo.getIndexes().isEmpty()
-                && !dsInfo.isExternal()) {
-            removeDatasetFromCache(dsInfo.getDatasetID());
+        synchronized (dsInfo) {
+            if (dsInfo.getReferenceCount() == 0 && dsInfo.isOpen() && 
dsInfo.getIndexes().isEmpty()
+                    && !dsInfo.isExternal()) {
+                removeDatasetFromCache(dsInfo.getDatasetID());
+            }
         }
     }
 
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
index 8afae0d..fa0f14c 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/Info.java
@@ -18,25 +18,26 @@
  */
 package org.apache.asterix.common.context;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 public abstract class Info {
-    private int referenceCount;
-    private boolean isOpen;
+    private final AtomicInteger referenceCount = new AtomicInteger();
+    private volatile boolean isOpen;
 
     public Info() {
-        referenceCount = 0;
         isOpen = false;
     }
 
     public void touch() {
-        ++referenceCount;
+        referenceCount.incrementAndGet();
     }
 
     public void untouch() {
-        --referenceCount;
+        referenceCount.decrementAndGet();
     }
 
     public int getReferenceCount() {
-        return referenceCount;
+        return referenceCount.get();
     }
 
     public boolean isOpen() {

Reply via email to