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();