private void InterruptableMethod() { UninterruptableMonitor.Enter(lock1); try { if (Verbose) { Console.WriteLine("acquired lock1 successfully"); Console.WriteLine("sleeping..."); } try { UninterruptableMonitor.Wait(lock1, TimeSpan.FromMilliseconds(200)); } catch (Exception ie) when(ie.IsInterruptedException()) { throw new Util.ThreadInterruptedException(ie); } } finally { UninterruptableMonitor.Exit(lock1); } }
public override void Run() { Random rnd = LuceneTestCase.Random; while (!stopped) { if (index % 2 == 0) { // refresh reader synchronized ReaderCouple c = (outerInstance.RefreshReader(r, test, index, true)); readersToClose.Add(c.newReader); readersToClose.Add(c.refreshedReader); readers.Add(c); // prevent too many readers break; } else { // not synchronized DirectoryReader refreshed = DirectoryReader.OpenIfChanged(r); if (refreshed == null) { refreshed = r; } IndexSearcher searcher = #if FEATURE_INSTANCE_TESTDATA_INITIALIZATION outerInstance. #endif NewSearcher(refreshed); ScoreDoc[] hits = searcher.Search(new TermQuery(new Term("field1", "a" + rnd.Next(refreshed.MaxDoc))), null, 1000).ScoreDocs; if (hits.Length > 0) { searcher.Doc(hits[0].Doc); } if (refreshed != r) { refreshed.Dispose(); } } UninterruptableMonitor.Enter(this); try { UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(TestUtil.NextInt32(Random, 1, 100))); } finally { UninterruptableMonitor.Exit(this); } } }
internal string[] Next() { if (t == null) { threadDone = false; t = new ThreadJob(Run); t.IsBackground = true; t.Start(); } string[] result; UninterruptableMonitor.Enter(this); try { while (tuple == null && nmde == null && !threadDone && !stopped) { try { UninterruptableMonitor.Wait(this); } catch (Exception ie) when(ie.IsInterruptedException()) { throw new Util.ThreadInterruptedException(ie); } } if (tuple != null) { result = tuple; tuple = null; Monitor.Pulse(this);// notify(); return(result); } if (nmde != null) { // Set to null so we will re-start thread in case // we are re-used: t = null; throw nmde; } // The thread has exited yet did not hit end of // data, so this means it hit an exception. We // throw NoMorDataException here to force // benchmark to stop the current alg: throw new NoMoreDataException(); } finally { UninterruptableMonitor.Exit(this); } }
public void WaitForFlush() { UninterruptableMonitor.Enter(this); try { while (flushingWriters.Count != 0) { try { UninterruptableMonitor.Wait(this); } catch (Exception ie) when(ie.IsInterruptedException()) { throw new Util.ThreadInterruptedException(ie); } } } finally { UninterruptableMonitor.Exit(this); } }
/// <summary> /// Blocks if documents writing is currently in a stalled state. /// /// </summary> internal void WaitIfStalled() { if (stalled) { UninterruptableMonitor.Enter(this); try { if (stalled) // react on the first wakeup call! { // don't loop here, higher level logic will re-stall! try { // LUCENENET: make sure not to run IncWaiters / DecrWaiters in Debugging.Assert as that gets // disabled in production var result = IncWaiters(); if (Debugging.AssertsEnabled) { Debugging.Assert(result); } UninterruptableMonitor.Wait(this); result = DecrWaiters(); if (Debugging.AssertsEnabled) { Debugging.Assert(result); } } catch (Exception ie) when(ie.IsInterruptedException()) { throw new Util.ThreadInterruptedException(ie); } } } finally { UninterruptableMonitor.Exit(this); } } }
public override void Run() { Random rnd = LuceneTestCase.Random; while (!stopped) { int numReaders = readers.Count; if (numReaders > 0) { ReaderCouple c = readers[rnd.Next(numReaders)]; TestDirectoryReader.AssertIndexEquals(c.newReader, c.refreshedReader); } UninterruptableMonitor.Enter(this); try { UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(TestUtil.NextInt32(Random, 1, 100))); } finally { UninterruptableMonitor.Exit(this); } } }
public override void Merge(IndexWriter writer, MergeTrigger trigger, bool newMergesFound) { UninterruptableMonitor.Enter(this); try { if (Debugging.AssertsEnabled) { Debugging.Assert(!UninterruptableMonitor.IsEntered(writer)); } this.m_writer = writer; InitMergeThreadPriority(); m_dir = writer.Directory; // First, quickly run through the newly proposed merges // and add any orthogonal merges (ie a merge not // involving segments already pending to be merged) to // the queue. If we are way behind on merging, many of // these newly proposed merges will likely already be // registered. if (IsVerbose) { Message("now merge"); Message(" index: " + writer.SegString()); } // Iterate, pulling from the IndexWriter's queue of // pending merges, until it's empty: while (true) { long startStallTime = 0; while (writer.HasPendingMerges() && MergeThreadCount >= maxMergeCount) { // this means merging has fallen too far behind: we // have already created maxMergeCount threads, and // now there's at least one more merge pending. // Note that only maxThreadCount of // those created merge threads will actually be // running; the rest will be paused (see // updateMergeThreads). We stall this producer // thread to prevent creation of new segments, // until merging has caught up: startStallTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results if (IsVerbose) { Message(" too many merges; stalling..."); } try { UninterruptableMonitor.Wait(this); } catch (Exception ie) when(ie.IsInterruptedException()) { throw new Util.ThreadInterruptedException(ie); } } if (IsVerbose) { if (startStallTime != 0) { Message(" stalled for " + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - startStallTime) + " msec"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results } } MergePolicy.OneMerge merge = writer.NextMerge(); if (merge == null) { if (IsVerbose) { Message(" no more merges pending; now return"); } return; } bool success = false; try { if (IsVerbose) { Message(" consider merge " + writer.SegString(merge.Segments)); } // OK to spawn a new merge thread to handle this // merge: MergeThread merger = GetMergeThread(writer, merge); m_mergeThreads.Add(merger); if (IsVerbose) { Message(" launch new thread [" + merger.Name + "]"); } merger.Start(); // Must call this after starting the thread else // the new thread is removed from mergeThreads // (since it's not alive yet): UpdateMergeThreads(); success = true; } finally { if (!success) { writer.MergeFinish(merge); } } } } finally { UninterruptableMonitor.Exit(this); } }
public virtual void TestThreadSafety() { Directory dir = NewDirectory(); // NOTE: this also controls the number of threads! int n = TestUtil.NextInt32(Random, 20, 40); IndexWriter writer = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random))); for (int i = 0; i < n; i++) { writer.AddDocument(CreateDocument(i, 3)); } writer.ForceMerge(1); writer.Dispose(); TestReopen test = new TestReopenAnonymousClass3(this, dir, n); IList <ReaderCouple> readers = new SynchronizedList <ReaderCouple>(); DirectoryReader firstReader = DirectoryReader.Open(dir); DirectoryReader reader = firstReader; ReaderThread[] threads = new ReaderThread[n]; ISet <DirectoryReader> readersToClose = new JCG.HashSet <DirectoryReader>().AsConcurrent(); for (int i = 0; i < n; i++) { if (i % 2 == 0) { DirectoryReader refreshed = DirectoryReader.OpenIfChanged(reader); if (refreshed != null) { readersToClose.Add(reader); reader = refreshed; } } DirectoryReader r = reader; int index = i; ReaderThreadTask task; if (i < 4 || (i >= 10 && i < 14) || i > 18) { task = new ReaderThreadTaskAnonymousClass(this, test, readers, readersToClose, r, index); } else { task = new ReaderThreadTaskAnonymousClass2(this, readers); } threads[i] = new ReaderThread(task); threads[i].Start(); } UninterruptableMonitor.Enter(this); try { UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(1000)); } finally { UninterruptableMonitor.Exit(this); } for (int i = 0; i < n; i++) { if (threads[i] != null) { threads[i].StopThread(); } } for (int i = 0; i < n; i++) { if (threads[i] != null) { threads[i].Join(); if (threads[i].error != null) { string msg = "Error occurred in thread " + threads[i].Name + ":\n" + threads[i].error.Message; Assert.Fail(msg); } } } foreach (DirectoryReader readerToClose in readersToClose) { readerToClose.Dispose(); } firstReader.Dispose(); reader.Dispose(); foreach (DirectoryReader readerToClose in readersToClose) { AssertReaderClosed(readerToClose, true); } AssertReaderClosed(reader, true); AssertReaderClosed(firstReader, true); dir.Dispose(); }
// LUCENENET: Called in one place, but since there is no implementation it is just wasted CPU //internal void Recycle(DocumentsWriterPerThread dwpt) //{ // // don't recycle DWPT by default //} // you cannot subclass this without being in o.a.l.index package anyway, so // the class is already pkg-private... fix me: see LUCENE-4013 public ThreadState GetAndLock(/* Thread requestingThread, DocumentsWriter documentsWriter // LUCENENET: Not referenced */) { ThreadState threadState = null; UninterruptableMonitor.Enter(this); try { for (;;) { if (freeCount > 0) { // Important that we are LIFO here! This way if number of concurrent indexing threads was once high, but has now reduced, we only use a // limited number of thread states: threadState = freeList[freeCount - 1]; if (threadState.dwpt == null) { // This thread-state is not initialized, e.g. it // was just flushed. See if we can instead find // another free thread state that already has docs // indexed. This way if incoming thread concurrency // has decreased, we don't leave docs // indefinitely buffered, tying up RAM. This // will instead get those thread states flushed, // freeing up RAM for larger segment flushes: for (int i = 0; i < freeCount; i++) { if (freeList[i].dwpt != null) { // Use this one instead, and swap it with // the un-initialized one: ThreadState ts = freeList[i]; freeList[i] = threadState; threadState = ts; break; } } } freeCount--; break; } else if (NumThreadStatesActive < threadStates.Length) { // ThreadState is already locked before return by this method: return(NewThreadState()); } else { // Wait until a thread state frees up: try { UninterruptableMonitor.Wait(this); } catch (Exception ie) when(ie.IsInterruptedException()) { throw new Util.ThreadInterruptedException(ie); } } } } finally { UninterruptableMonitor.Exit(this); } // This could take time, e.g. if the threadState is [briefly] checked for flushing: threadState.Lock(); return(threadState); }
public override void EndElement(string @namespace, string simple, string qualified) { int elemType = GetElementType(qualified); switch (elemType) { case PAGE: // the body must be null and we either are keeping image docs or the // title does not start with Image: if (body != null && (outerInstance.keepImages || !title.StartsWith("Image:", StringComparison.Ordinal))) { string[] tmpTuple = new string[LENGTH]; tmpTuple[TITLE] = title.Replace('\t', ' '); tmpTuple[DATE] = time.Replace('\t', ' '); tmpTuple[BODY] = Regex.Replace(body, "[\t\n]", " "); tmpTuple[ID] = id; UninterruptableMonitor.Enter(this); try { while (tuple != null && !stopped) { try { UninterruptableMonitor.Wait(this); //wait(); } catch (System.Threading.ThreadInterruptedException ie) { throw new Util.ThreadInterruptedException(ie); } } tuple = tmpTuple; UninterruptableMonitor.Pulse(this); //notify(); } finally { UninterruptableMonitor.Exit(this); } } break; case BODY: body = contents.ToString(); //workaround that startswith doesn't have an ignore case option, get at least 10 chars. string startsWith = body.Substring(0, Math.Min(10, contents.Length) - 0).ToLowerInvariant(); if (startsWith.StartsWith("#redirect", StringComparison.Ordinal)) { body = null; } break; case DATE: time = Time(contents.ToString()); break; case TITLE: title = contents.ToString(); break; case ID: //the doc id is the first one in the page. All other ids after that one can be ignored according to the schema if (id == null) { id = contents.ToString(); } break; default: // this element should be discarded. break; } }