Browse Source

Fix race condition in NodeEnvironment.close() (#94677)

Simon Cooper 2 years ago
parent
commit
b452cf5de7

+ 6 - 0
docs/changelog/94677.yaml

@@ -0,0 +1,6 @@
+pr: 94677
+summary: Fix race condition in `NodeEnvironment.close()`
+area: Infra/Core
+type: bug
+issues:
+ - 94672

+ 17 - 12
server/src/main/java/org/elasticsearch/env/NodeEnvironment.java

@@ -1265,12 +1265,14 @@ public final class NodeEnvironment implements Closeable {
     @Override
     public void close() {
         if (closed.compareAndSet(false, true) && locks != null) {
-            for (Lock lock : locks) {
-                try {
-                    logger.trace("releasing lock [{}]", lock);
-                    lock.close();
-                } catch (IOException e) {
-                    logger.trace(() -> "failed to release lock [" + lock + "]", e);
+            synchronized (locks) {
+                for (Lock lock : locks) {
+                    try {
+                        logger.trace("releasing lock [{}]", lock);
+                        lock.close();
+                    } catch (IOException e) {
+                        logger.trace(() -> "failed to release lock [" + lock + "]", e);
+                    }
                 }
             }
         }
@@ -1278,12 +1280,15 @@ public final class NodeEnvironment implements Closeable {
 
     private void assertEnvIsLocked() {
         if (closed.get() == false && locks != null) {
-            for (Lock lock : locks) {
-                try {
-                    lock.ensureValid();
-                } catch (IOException e) {
-                    logger.warn("lock assertion failed", e);
-                    throw new IllegalStateException("environment is not locked", e);
+            synchronized (locks) {
+                if (closed.get()) return; // raced with close() - we lost
+                for (Lock lock : locks) {
+                    try {
+                        lock.ensureValid();
+                    } catch (IOException e) {
+                        logger.warn("lock assertion failed", e);
+                        throw new IllegalStateException("environment is not locked", e);
+                    }
                 }
             }
         }