/* * FlushAllThreads is synced by IW fullFlushLock. Flushing all threads is a * two stage operation; the caller must ensure (in try/finally) that finishFlush * is called after this method, to release the flush lock in DWFlushControl */ internal bool FlushAllThreads(IndexWriter indexWriter) { DocumentsWriterDeleteQueue flushingDeleteQueue; if (infoStream.IsEnabled("DW")) { infoStream.Message("DW", "startFullFlush"); } lock (this) { pendingChangesInCurrentFullFlush = AnyChanges(); flushingDeleteQueue = deleteQueue; /* Cutover to a new delete queue. this must be synced on the flush control * otherwise a new DWPT could sneak into the loop with an already flushing * delete queue */ flushControl.MarkForFullFlush(); // swaps the delQueue synced on FlushControl Debug.Assert(SetFlushingDeleteQueue(flushingDeleteQueue)); } Debug.Assert(currentFullFlushDelQueue != null); Debug.Assert(currentFullFlushDelQueue != deleteQueue); bool anythingFlushed = false; try { DocumentsWriterPerThread flushingDWPT; // Help out with flushing: while ((flushingDWPT = flushControl.NextPendingFlush()) != null) { anythingFlushed |= DoFlush(flushingDWPT); } // If a concurrent flush is still in flight wait for it flushControl.WaitForFlush(); if (!anythingFlushed && flushingDeleteQueue.AnyChanges()) // apply deletes if we did not flush any document { if (infoStream.IsEnabled("DW")) { infoStream.Message("DW", Thread.CurrentThread.Name + ": flush naked frozen global deletes"); } ticketQueue.AddDeletes(flushingDeleteQueue); } ticketQueue.ForcePurge(indexWriter); Debug.Assert(!flushingDeleteQueue.AnyChanges() && !ticketQueue.HasTickets); } finally { Debug.Assert(flushingDeleteQueue == currentFullFlushDelQueue); } return(anythingFlushed); }