TestIndexWriterOnVMError.testUnknownError times out (fixes potential IW deadlock on tragic exceptions). (#12751)

This commit is contained in:
Dawid Weiss 2023-11-08 09:47:19 +01:00 committed by GitHub
parent f416b2b8b5
commit c85529b2c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 29 deletions

View File

@ -273,6 +273,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)

View File

@ -2464,6 +2464,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
@ -2532,42 +2543,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;
}
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;
// 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 {