Exemple #1
0
        public virtual void TestAccquireReleaseRace()
        {
            DocumentsWriterStallControl ctrl = new DocumentsWriterStallControl();

            ctrl.UpdateStalled(false);
            AtomicBoolean stop       = new AtomicBoolean(false);
            AtomicBoolean checkPoint = new AtomicBoolean(true);

            int numStallers              = AtLeast(1);
            int numReleasers             = AtLeast(1);
            int numWaiters               = AtLeast(1);
            var sync                     = new Synchronizer(numStallers + numReleasers, numStallers + numReleasers + numWaiters);
            var threads                  = new ThreadJob[numReleasers + numStallers + numWaiters];
            IList <Exception> exceptions = new SynchronizedList <Exception>();

            for (int i = 0; i < numReleasers; i++)
            {
                threads[i] = new Updater(stop, checkPoint, ctrl, sync, true, exceptions);
            }
            for (int i = numReleasers; i < numReleasers + numStallers; i++)
            {
                threads[i] = new Updater(stop, checkPoint, ctrl, sync, false, exceptions);
            }
            for (int i = numReleasers + numStallers; i < numReleasers + numStallers + numWaiters; i++)
            {
                threads[i] = new Waiter(stop, checkPoint, ctrl, sync, exceptions);
            }

            Start(threads);
            int   iters = AtLeast(10000);
            float checkPointProbability = TestNightly ? 0.5f : 0.1f;

            for (int i = 0; i < iters; i++)
            {
                if (checkPoint)
                {
                    Assert.IsTrue(sync.updateJoin.Wait(new TimeSpan(0, 0, 0, 10)), "timed out waiting for update threads - deadlock?");
                    if (exceptions.Count > 0)
                    {
                        foreach (Exception throwable in exceptions)
                        {
                            Console.WriteLine(throwable.ToString());
                            Console.Write(throwable.StackTrace);
                        }
                        Assert.Fail("got exceptions in threads");
                    }

                    if (ctrl.HasBlocked && ctrl.IsHealthy)
                    {
                        AssertState(numReleasers, numStallers, numWaiters, threads, ctrl);
                    }

                    checkPoint.Value = (false);
                    sync.waiter.Signal();
                    sync.leftCheckpoint.Wait();
                }
                Assert.IsFalse(checkPoint);
                Assert.AreEqual(0, sync.waiter.CurrentCount);
                if (checkPointProbability >= (float)Random.NextDouble())
                {
                    sync.Reset(numStallers + numReleasers, numStallers + numReleasers + numWaiters);
                    checkPoint.Value = (true);
                }
            }
            if (!checkPoint)
            {
                sync.Reset(numStallers + numReleasers, numStallers + numReleasers + numWaiters);
                checkPoint.Value = (true);
            }

            Assert.IsTrue(sync.updateJoin.Wait(new TimeSpan(0, 0, 0, 10)));
            AssertState(numReleasers, numStallers, numWaiters, threads, ctrl);
            checkPoint.Value = (false);
            stop.Value       = (true);
            sync.waiter.Signal();
            sync.leftCheckpoint.Wait();

            for (int i = 0; i < threads.Length; i++)
            {
                ctrl.UpdateStalled(false);
                threads[i].Join(2000);
                if (threads[i].IsAlive && threads[i] is Waiter)
                {
                    if (threads[i].State == ThreadState.WaitSleepJoin)
                    {
                        Assert.Fail("waiter is not released - anyThreadsStalled: " + ctrl.AnyStalledThreads());
                    }
                }
            }
        }
        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();
            }

            lock (this)
            {
                Monitor.Wait(this, TimeSpan.FromMilliseconds(1000));
            }

            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();
        }