private void FinishMerges(bool waitForMerges)
{
lock (this)
{
if (!waitForMerges)
{
stopMerges = true;
// Abort all pending & running merges:
foreach(MergePolicy.OneMerge merge in pendingMerges)
{
if (infoStream != null)
Message("now abort pending merge " + merge.SegString(directory));
merge.Abort();
MergeFinish(merge);
}
pendingMerges.Clear();
foreach(MergePolicy.OneMerge merge in runningMerges)
{
if (infoStream != null)
Message("now abort running merge " + merge.SegString(directory));
merge.Abort();
}
// Ensure any running addIndexes finishes. It's fine
// if a new one attempts to start because its merges
// will quickly see the stopMerges == true and abort.
AcquireRead();
ReleaseRead();
// These merges periodically check whether they have
// been aborted, and stop if so. We wait here to make
// sure they all stop. It should not take very long
// because the merge threads periodically check if
// they are aborted.
while (runningMerges.Count > 0)
{
if (infoStream != null)
Message("now wait for " + runningMerges.Count + " running merge to abort");
DoWait();
}
stopMerges = false;
System.Threading.Monitor.PulseAll(this);
System.Diagnostics.Debug.Assert(0 == mergingSegments.Count);
if (infoStream != null)
Message("all running merges have aborted");
}
else
{
// waitForMerges() will ensure any running addIndexes finishes.
// It's fine if a new one attempts to start because from our
// caller above the call will see that we are in the
// process of closing, and will throw an
// AlreadyClosedException.
WaitForMerges();
}
}
}