LUCENE-3705: IWFlushQueue deadlocks if deletes are flushed and a segment is published at the same time

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1233248 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Simon Willnauer 2012-01-19 08:54:33 +00:00
parent fb1884358d
commit 52dc6a5908
1 changed files with 17 additions and 10 deletions

View File

@ -34,19 +34,24 @@ public class DocumentsWriterFlushQueue {
private final AtomicInteger ticketCount = new AtomicInteger(); private final AtomicInteger ticketCount = new AtomicInteger();
private final ReentrantLock purgeLock = new ReentrantLock(); private final ReentrantLock purgeLock = new ReentrantLock();
synchronized void addDeletesAndPurge(DocumentsWriter writer, void addDeletesAndPurge(DocumentsWriter writer,
DocumentsWriterDeleteQueue deleteQueue) throws IOException { DocumentsWriterDeleteQueue deleteQueue) throws IOException {
synchronized (this) {
incTickets();// first inc the ticket count - freeze opens incTickets();// first inc the ticket count - freeze opens
// a window for #anyChanges to fail // a window for #anyChanges to fail
boolean success = false; boolean success = false;
try { try {
queue.add(new GlobalDeletesTicket(deleteQueue.freezeGlobalBuffer(null))); queue
.add(new GlobalDeletesTicket(deleteQueue.freezeGlobalBuffer(null)));
success = true; success = true;
} finally { } finally {
if (!success) { if (!success) {
decTickets(); decTickets();
} }
} }
}
// don't hold the lock on the FlushQueue when forcing the purge - this blocks and deadlocks
// if we hold the lock.
forcePurge(writer); forcePurge(writer);
} }
@ -127,6 +132,7 @@ public class DocumentsWriterFlushQueue {
} }
void forcePurge(DocumentsWriter writer) throws IOException { void forcePurge(DocumentsWriter writer) throws IOException {
assert !Thread.holdsLock(this);
purgeLock.lock(); purgeLock.lock();
try { try {
innerPurge(writer); innerPurge(writer);
@ -136,6 +142,7 @@ public class DocumentsWriterFlushQueue {
} }
void tryPurge(DocumentsWriter writer) throws IOException { void tryPurge(DocumentsWriter writer) throws IOException {
assert !Thread.holdsLock(this);
if (purgeLock.tryLock()) { if (purgeLock.tryLock()) {
try { try {
innerPurge(writer); innerPurge(writer);