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

jinmeiliao pushed a commit to branch feature/GEODE-7665
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/feature/GEODE-7665 by this 
push:
     new fec5471  GEODE-8771: invalidate should acquire the lock before 
initIndex (#5823)
fec5471 is described below

commit fec54719ae6e0d753f6e50f901b3a25279c62740
Author: Jinmei Liao <[email protected]>
AuthorDate: Fri Dec 11 09:23:59 2020 -0800

    GEODE-8771: invalidate should acquire the lock before initIndex (#5823)
---
 .../query/partitioned/PRClearIntegrationTest.java  | 73 ++++++++++++++++++++++
 .../geode/internal/cache/AbstractRegionMap.java    | 20 +++---
 .../cache/versions/RegionVersionVector.java        |  4 +-
 3 files changed, 86 insertions(+), 11 deletions(-)

diff --git 
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRClearIntegrationTest.java
 
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRClearIntegrationTest.java
new file mode 100644
index 0000000..894db1b
--- /dev/null
+++ 
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/partitioned/PRClearIntegrationTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.query.partitioned;
+
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.geode.cache.EntryNotFoundException;
+import org.apache.geode.cache.Region;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.junit.rules.ExecutorServiceRule;
+import org.apache.geode.test.junit.rules.ServerStarterRule;
+
+public class PRClearIntegrationTest {
+
+  @Rule
+  public ServerStarterRule server = new ServerStarterRule().withAutoStart();
+
+  @Rule
+  public ExecutorServiceRule executor = new ExecutorServiceRule();
+
+  @Test
+  public void doesNotHangWhenClearWithConcurrentPutsAndInvalidates() throws 
Exception {
+    InternalCache cache = server.getCache();
+    Region<Object, Object> region = server.createPartitionRegion("regionA", f 
-> {
+    }, f -> f.setTotalNumBuckets(1));
+    cache.getQueryService().createIndex("indexA", "r", "/regionA r");
+    region.put(0, "value0");
+
+    CompletableFuture<Void> put = executor.runAsync(() -> {
+      Thread.currentThread().setName("put-Thread");
+      IntStream.range(0, 10).forEach(i -> region.put(i, "value" + i));
+    });
+
+    CompletableFuture<Void> invalidate = executor.runAsync(() -> {
+      Thread.currentThread().setName("invalidate-Thread");
+      IntStream.range(0, 10).forEach(i -> {
+        try {
+          region.invalidate(i);
+        } catch (EntryNotFoundException e) {
+          // ignore
+        }
+      });
+    });
+
+    CompletableFuture<Void> clear = executor.runAsync(() -> {
+      Thread.currentThread().setName("Clear-Thread");
+      IntStream.range(0, 10).forEach(i -> region.clear());
+    });
+
+    put.get(5, TimeUnit.SECONDS);
+    invalidate.get(5, TimeUnit.SECONDS);
+    clear.get(5, TimeUnit.SECONDS);
+  }
+}
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
index d4f7b45..7c0ea5b 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
@@ -1282,16 +1282,19 @@ public abstract class AbstractRegionMap extends 
BaseRegionMap
     DiskRegion dr = owner.getDiskRegion();
     boolean ownerIsInitialized = owner.isInitialized();
 
-    // Fix for Bug #44431. We do NOT want to update the region and wait
-    // later for index INIT as region.clear() can cause inconsistency if
-    // happened in parallel as it also does index INIT.
-    IndexManager oqlIndexManager = owner.getIndexManager();
-    if (oqlIndexManager != null) {
-      oqlIndexManager.waitForIndexInit();
-    }
+    // lock before waitForIndexInit so that we should wait
+    // till a concurrent clear to finish
     lockForCacheModification(owner, event);
-    final boolean locked = owner.lockWhenRegionIsInitializing();
+    boolean locked = false;
     try {
+      // Fix for Bug #44431. We do NOT want to update the region and wait
+      // later for index INIT as region.clear() can cause inconsistency if
+      // happened in parallel as it also does index INIT.
+      IndexManager oqlIndexManager = owner.getIndexManager();
+      if (oqlIndexManager != null) {
+        oqlIndexManager.waitForIndexInit();
+      }
+      locked = owner.lockWhenRegionIsInitializing();
       try {
         try {
           if (forceNewEntry || forceCallbacks) {
@@ -1660,7 +1663,6 @@ public abstract class AbstractRegionMap extends 
BaseRegionMap
       }
       releaseCacheModificationLock(owner, event);
     }
-
   }
 
   /**
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/versions/RegionVersionVector.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/versions/RegionVersionVector.java
index 13a0da7..5272f10 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/cache/versions/RegionVersionVector.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/versions/RegionVersionVector.java
@@ -320,7 +320,7 @@ public abstract class RegionVersionVector<T extends 
VersionSource<?>>
         // this method is invoked by memberDeparted events and may not be for 
the current lock owner
         return;
       }
-      unlockVersionGeneration(locker);
+      unlockVersionGeneration();
     }
   }
 
@@ -416,7 +416,7 @@ public abstract class RegionVersionVector<T extends 
VersionSource<?>>
 
   }
 
-  private void unlockVersionGeneration(final InternalDistributedMember locker) 
{
+  private void unlockVersionGeneration() {
     synchronized (clearLockSync) {
       this.doUnlock = true;
       this.clearLockSync.notifyAll();

Reply via email to