Пример #1
0
        public void ShouldNotReturnNextClaimSequenceUntilBufferHasReserve()
        {
            var dependentSequence = new Sequence(Sequencer.InitialCursorValue);

            Sequence[] dependentSequences = { dependentSequence };
            _claimStrategy.SetSequence(_claimStrategy.BufferSize - 1L, dependentSequences);

            var done        = new Volatile4.Boolean(false);
            var beforeLatch = new ManualResetEvent(false);
            var afterLatch  = new ManualResetEvent(false);

            new Thread(
                () =>
            {
                beforeLatch.Set();

                Assert.AreEqual(_claimStrategy.BufferSize, _claimStrategy.IncrementAndGet(dependentSequences));

                done.WriteFullFence(true);
                afterLatch.Set();
            }).Start();

            beforeLatch.WaitOne();

            Thread.Sleep(100);
            Assert.IsFalse(done.ReadFullFence());

            dependentSequence.Value = (dependentSequence.Value + 1L);

            afterLatch.WaitOne();
            Assert.AreEqual(_claimStrategy.BufferSize, _claimStrategy.Sequence);
        }
Пример #2
0
 private void CheckNotStarted()
 {
     if (_running.ReadFullFence())
     {
         throw new InvalidOperationException("All event handlers must be added before calling starts.");
     }
 }
Пример #3
0
        /// <summary>
        /// It is ok to have another thread re-run this method after a halt().
        /// </summary>
        public void Run()
        {
            if (!_running.AtomicCompareExchange(Running, Stopped))
            {
                throw new InvalidOperationException("Thread is already running");
            }
            _sequenceBarrier.ClearAlert();

            NotifyStart();

            var  processedSequence = true;
            long nextSequence      = _sequence.Value;
            T    eventRef          = null;

            while (true)
            {
                try
                {
                    if (processedSequence)
                    {
                        processedSequence = false;
                        nextSequence      = _workSequence.IncrementAndGet();
                        _sequence.Value   = nextSequence - 1L;
                    }

                    _sequenceBarrier.WaitFor(nextSequence);
                    eventRef = _ringBuffer[nextSequence];
                    _workHandler.OnEvent(eventRef);

                    processedSequence = true;
                }
                catch (AlertException)
                {
                    if (_running.ReadFullFence() == Stopped)
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    _exceptionHandler.HandleEventException(ex, nextSequence, eventRef);
                    processedSequence = true;
                }
            }

            NotifyShutdown();

            _running.WriteFullFence(Stopped);
        }
Пример #4
0
        /// <summary>
        /// It is ok to have another thread rerun this method after a halt().
        /// </summary>
        public void Run()
        {
            if (!_running.AtomicCompareExchange(Running, Stopped))
            {
                throw new InvalidOperationException("Thread is already running");
            }
            _sequenceBarrier.ClearAlert();

            NotifyStart();

            T    evt          = null;
            long nextSequence = _sequence.Value + 1L;

            while (true)
            {
                try
                {
                    long availableSequence = _sequenceBarrier.WaitFor(nextSequence);
                    while (nextSequence <= availableSequence)
                    {
                        evt = _ringBuffer[nextSequence];
                        _eventHandler.OnNext(evt, nextSequence, nextSequence == availableSequence);
                        nextSequence++;
                    }

                    _sequence.LazySet(nextSequence - 1L);
                }
                catch (AlertException)
                {
                    if (!_running.ReadFullFence())
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    _exceptionHandler.HandleEventException(ex, nextSequence, evt);
                    _sequence.LazySet(nextSequence);
                    nextSequence++;
                }
            }

            NotifyShutdown();

            _running.WriteFullFence(Stopped);
        }
        public void ShouldNotReturnNextClaimSequenceUntilBufferHasReserve()
        {
            var dependentSequence = new Sequence(Sequencer.InitialCursorValue);
            var dependentSequences = new[] { dependentSequence };
            _claimStrategy.SetSequence(BufferSize - 1L, dependentSequences);

            var done = new Volatile4.Boolean(false);
            var beforeLatch = new ManualResetEvent(false);
            var afterLatch = new ManualResetEvent(false);

            new Thread(() =>
                           {
                               beforeLatch.Set();

                               Assert.AreEqual(_claimStrategy.BufferSize,
                                               _claimStrategy.IncrementAndGet(dependentSequences));

                               done.WriteFullFence(true);
                               afterLatch.Set();
                           }).Start();

            beforeLatch.WaitOne();

            Thread.Sleep(1000);
            Assert.IsFalse(done.ReadFullFence());

            dependentSequence.Value = dependentSequence.Value + 1L;

            afterLatch.WaitOne();
            Assert.AreEqual(_claimStrategy.BufferSize, _claimStrategy.Sequence);
        }
 public void ReadFullFenceReturnsInitialValue()
 {
     Assert.AreEqual(InitialValue, _volatile.ReadFullFence());
 }