You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2023/11/08 08:58:13 UTC

(lucene) branch branch_9x updated: TestIndexWriterOnVMError.testUnknownError times out (fixes potential IW deadlock on tragic exceptions). (#12751)

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

dweiss pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new 15596df1328 TestIndexWriterOnVMError.testUnknownError times out (fixes potential IW deadlock on tragic exceptions). (#12751)
15596df1328 is described below

commit 15596df1328f75c3394593694af37bc996429801
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Wed Nov 8 09:47:19 2023 +0100

    TestIndexWriterOnVMError.testUnknownError times out (fixes potential IW deadlock on tragic exceptions). (#12751)
---
 lucene/CHANGES.txt                                 |  3 ++
 .../java/org/apache/lucene/index/IndexWriter.java  | 62 ++++++++++++----------
 2 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 7319f60c01e..0902a08e250 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -136,6 +136,9 @@ Changes in runtime behavior
 Bug Fixes
 ---------------------
 
+* GITHUB#12654: TestIndexWriterOnVMError.testUnknownError times out (fixes potential IndexWriter
+  deadlock with tragic exceptions). (Benjamin Trent, Dawid Weiss, Simon Willnauer)
+
 * GITHUB#12614: Make LRUQueryCache respect Accountable queries on eviction and consistency check
   (Grigoriy Troitskiy)
 
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
index 0c6775d753e..318884a6c20 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
@@ -2465,6 +2465,17 @@ public class IndexWriter
       infoStream.message("IW", "rollback");
     }
 
+    Closeable cleanupAndNotify =
+        () -> {
+          assert Thread.holdsLock(this);
+          writeLock = null;
+          closed = true;
+          closing = false;
+          // So any "concurrently closing" threads wake up and see that the close has now
+          // completed:
+          notifyAll();
+        };
+
     try {
       synchronized (this) {
         // must be synced otherwise register merge might throw and exception if merges
@@ -2533,42 +2544,35 @@ public class IndexWriter
         // below that sets closed:
         closed = true;
 
-        IOUtils.close(writeLock); // release write lock
-        writeLock = null;
-        closed = true;
-        closing = false;
-        // So any "concurrently closing" threads wake up and see that the close has now completed:
-        notifyAll();
+        IOUtils.close(writeLock, cleanupAndNotify);
       }
     } catch (Throwable throwable) {
       try {
         // Must not hold IW's lock while closing
         // mergeScheduler: this can lead to deadlock,
         // e.g. TestIW.testThreadInterruptDeadlock
-        IOUtils.closeWhileHandlingException(mergeScheduler);
-        synchronized (this) {
-          // we tried to be nice about it: do the minimum
-          // don't leak a segments_N file if there is a pending commit
-          if (pendingCommit != null) {
-            try {
-              pendingCommit.rollbackCommit(directory);
-              deleter.decRef(pendingCommit);
-            } catch (Throwable t) {
-              throwable.addSuppressed(t);
-            }
-            pendingCommit = null;
-          }
-
-          // close all the closeables we can (but important is readerPool and writeLock to prevent
-          // leaks)
-          IOUtils.closeWhileHandlingException(readerPool, deleter, writeLock);
-          writeLock = null;
-          closed = true;
-          closing = false;
+        IOUtils.closeWhileHandlingException(
+            mergeScheduler,
+            () -> {
+              synchronized (this) {
+                // we tried to be nice about it: do the minimum
+                // don't leak a segments_N file if there is a pending commit
+                if (pendingCommit != null) {
+                  try {
+                    pendingCommit.rollbackCommit(directory);
+                    deleter.decRef(pendingCommit);
+                  } catch (Throwable t) {
+                    throwable.addSuppressed(t);
+                  }
+                  pendingCommit = null;
+                }
 
-          // So any "concurrently closing" threads wake up and see that the close has now completed:
-          notifyAll();
-        }
+                // close all the closeables we can (but important is readerPool and writeLock to
+                // prevent leaks)
+                IOUtils.closeWhileHandlingException(
+                    readerPool, deleter, writeLock, cleanupAndNotify);
+              }
+            });
       } catch (Throwable t) {
         throwable.addSuppressed(t);
       } finally {