internal void Abort(IndexWriter writer) { lock (this) { //Debug.Assert(!Thread.HoldsLock(writer), "IndexWriter lock should never be hold when aborting"); bool success = false; HashSet <string> newFilesSet = new HashSet <string>(); try { deleteQueue.Clear(); if (infoStream.IsEnabled("DW")) { infoStream.Message("DW", "abort"); } int limit = perThreadPool.NumThreadStatesActive; for (int i = 0; i < limit; i++) { ThreadState perThread = perThreadPool.GetThreadState(i); perThread.@Lock(); try { AbortThreadState(perThread, newFilesSet); } finally { perThread.Unlock(); } } flushControl.AbortPendingFlushes(newFilesSet); PutEvent(new DeleteNewFilesEvent(newFilesSet)); flushControl.WaitForFlush(); success = true; } finally { if (infoStream.IsEnabled("DW")) { infoStream.Message("DW", "done abort; abortedFiles=" + Arrays.ToString(newFilesSet) + " success=" + success); } } } }
public int NumThreadStatesActive => numThreadStatesActive; // LUCENENET NOTE: Changed from getActiveThreadState() because the name wasn't clear /// <summary> /// Returns a new <see cref="ThreadState"/> iff any new state is available otherwise /// <c>null</c>. /// <para/> /// NOTE: the returned <see cref="ThreadState"/> is already locked iff non-<c>null</c>. /// </summary> /// <returns> a new <see cref="ThreadState"/> iff any new state is available otherwise /// <c>null</c> </returns> public ThreadState NewThreadState() { if (Debugging.AssertsEnabled) { Debugging.Assert(numThreadStatesActive < threadStates.Length); } ThreadState threadState = threadStates[numThreadStatesActive]; threadState.Lock(); // lock so nobody else will get this ThreadState bool unlock = true; try { if (threadState.IsActive) { // unreleased thread states are deactivated during DW#close() numThreadStatesActive++; // increment will publish the ThreadState //System.out.println("activeCount=" + numThreadStatesActive); if (Debugging.AssertsEnabled) { Debugging.Assert(threadState.dwpt == null); } unlock = false; return(threadState); } // we are closed: unlock since the threadstate is not active anymore if (Debugging.AssertsEnabled) { Debugging.Assert(AssertUnreleasedThreadStatesInactive()); } return(null); } finally { if (unlock) { // in any case make sure we unlock if we fail threadState.Unlock(); } } }
internal DocumentsWriterPerThread NextPendingFlush() { int numPending; bool fullFlush; lock (this) { DocumentsWriterPerThread poll; if (flushQueue.Count > 0 && (poll = flushQueue.Dequeue()) != null) { UpdateStallState(); return(poll); } fullFlush = this.fullFlush; numPending = this.numPending; } if (numPending > 0 && !fullFlush) // don't check if we are doing a full flush { int limit = perThreadPool.NumThreadStatesActive; for (int i = 0; i < limit && numPending > 0; i++) { ThreadState next = perThreadPool.GetThreadState(i); if (next.flushPending && next.TryLock()) // LUCENENET specific: Since .NET Core 2+ uses fair locking, we need to ensure we have a lock before calling InternalTryCheckoutForFlush. See # { try { DocumentsWriterPerThread dwpt = TryCheckoutForFlush(next); if (dwpt != null) { return(dwpt); } } finally { next.Unlock(); } } } } return(null); }
private void CheckoutAndBlock(ThreadState perThread) { perThread.@Lock(); try { if (Debugging.AssertsEnabled) { Debugging.Assert(perThread.flushPending, "can not block non-pending threadstate"); Debugging.Assert(fullFlush, "can not block if fullFlush == false"); } DocumentsWriterPerThread dwpt; long bytes = perThread.bytesUsed; dwpt = DocumentsWriterPerThreadPool.Reset(perThread, closed); // LUCENENET specific - made method static per CA1822 numPending--; blockedFlushes.AddLast(new BlockedFlush(dwpt, bytes)); } finally { perThread.Unlock(); } }
/// <summary> /// Returns the number of currently deactivated <see cref="ThreadState"/> instances. /// A deactivated <see cref="ThreadState"/> should not be used for indexing anymore. /// </summary> /// <returns> the number of currently deactivated <see cref="ThreadState"/> instances. </returns> internal virtual int NumDeactivatedThreadStates() { int count = 0; for (int i = 0; i < threadStates.Length; i++) { ThreadState threadState = threadStates[i]; threadState.@Lock(); try { if (!threadState.isActive) { count++; } } finally { threadState.Unlock(); } } return(count); }
internal void UnlockAllAfterAbortAll(IndexWriter indexWriter) { UninterruptableMonitor.Enter(this); try { if (Debugging.AssertsEnabled) { Debugging.Assert(indexWriter.HoldsFullFlushLock); } if (infoStream.IsEnabled("DW")) { infoStream.Message("DW", "unlockAll"); } int limit = perThreadPool.MaxThreadStates; for (int i = 0; i < limit; i++) { try { ThreadState perThread = perThreadPool.GetThreadState(i); if (perThread.IsHeldByCurrentThread) { perThread.Unlock(); } } catch (Exception e) when(e.IsThrowable()) { if (infoStream.IsEnabled("DW")) { infoStream.Message("DW", "unlockAll: could not unlock state: " + i + " msg:" + e.Message); } // ignore & keep on unlocking } } } finally { UninterruptableMonitor.Exit(this); } }
private bool AssertActiveDeleteQueue(DocumentsWriterDeleteQueue queue) { int limit = perThreadPool.NumThreadStatesActive; for (int i = 0; i < limit; i++) { ThreadState next = perThreadPool.GetThreadState(i); next.@Lock(); try { if (Debugging.AssertsEnabled) { Debugging.Assert(!next.IsInitialized || next.dwpt.deleteQueue == queue, "isInitialized: {0} numDocs: {1}", next.IsInitialized, (next.IsInitialized ? next.dwpt.NumDocsInRAM : 0)); } } finally { next.Unlock(); } } return(true); }
private DocumentsWriterPerThread InternalTryCheckOutForFlush(ThreadState perThread) { //Debug.Assert(Thread.HoldsLock(this)); Debug.Assert(perThread.flushPending); try { // We are pending so all memory is already moved to flushBytes if (perThread.TryLock()) { try { if (perThread.IsInitialized) { //Debug.Assert(perThread.HeldByCurrentThread); DocumentsWriterPerThread dwpt; long bytes = perThread.bytesUsed; // do that before // replace! dwpt = perThreadPool.Reset(perThread, closed); Debug.Assert(!flushingWriters.ContainsKey(dwpt), "DWPT is already flushing"); // Record the flushing DWPT to reduce flushBytes in doAfterFlush flushingWriters[dwpt] = Convert.ToInt64(bytes); numPending--; // write access synced return(dwpt); } } finally { perThread.Unlock(); } } return(null); } finally { UpdateStallState(); } }
/// <summary> /// Deactivate all unreleased threadstates /// </summary> internal void DeactivateUnreleasedStates() { UninterruptableMonitor.Enter(this); try { for (int i = numThreadStatesActive; i < threadStates.Length; i++) { ThreadState threadState = threadStates[i]; threadState.@Lock(); try { threadState.Deactivate(); } finally { threadState.Unlock(); } } } finally { UninterruptableMonitor.Exit(this); } }
internal void MarkForFullFlush() { DocumentsWriterDeleteQueue flushingQueue; lock (this) { Debug.Assert(!fullFlush, "called DWFC#markForFullFlush() while full flush is still running"); Debug.Assert(fullFlushBuffer.Count == 0, "full flush buffer should be empty: " + fullFlushBuffer); fullFlush = true; flushingQueue = documentsWriter.deleteQueue; // Set a new delete queue - all subsequent DWPT will use this queue until // we do another full flush DocumentsWriterDeleteQueue newQueue = new DocumentsWriterDeleteQueue(flushingQueue.generation + 1); documentsWriter.deleteQueue = newQueue; } int limit = perThreadPool.NumThreadStatesActive; for (int i = 0; i < limit; i++) { ThreadState next = perThreadPool.GetThreadState(i); next.@Lock(); try { if (!next.IsInitialized) { if (closed && next.IsActive) { perThreadPool.DeactivateThreadState(next); } continue; } Debug.Assert(next.dwpt.deleteQueue == flushingQueue || next.dwpt.deleteQueue == documentsWriter.deleteQueue, " flushingQueue: " + flushingQueue + " currentqueue: " + documentsWriter.deleteQueue + " perThread queue: " + next.dwpt.deleteQueue + " numDocsInRam: " + next.dwpt.NumDocsInRAM); if (next.dwpt.deleteQueue != flushingQueue) { // this one is already a new DWPT continue; } AddFlushableState(next); } finally { next.Unlock(); } } lock (this) { /* make sure we move all DWPT that are where concurrently marked as * pending and moved to blocked are moved over to the flushQueue. There is * a chance that this happens since we marking DWPT for full flush without * blocking indexing.*/ PruneBlockedQueue(flushingQueue); Debug.Assert(AssertBlockedFlushes(documentsWriter.deleteQueue)); //FlushQueue.AddAll(FullFlushBuffer); foreach (var dwpt in fullFlushBuffer) { flushQueue.Enqueue(dwpt); } fullFlushBuffer.Clear(); UpdateStallState(); } Debug.Assert(AssertActiveDeleteQueue(documentsWriter.deleteQueue)); }