SetValue() public method

Perform an ordered write of this sequence. The intent is a Store/Store barrier between this write and any previous store.
public SetValue ( long value ) : void
value long The new value for the sequence.
return void
示例#1
0
        /// <summary>
        /// It is ok to have another thread rerun this method after a halt().
        /// </summary>
        public void Run()
        {
            if (Interlocked.Exchange(ref _running, 1) != 0)
            {
                throw new InvalidOperationException("Thread is already running");
            }
            _sequenceBarrier.ClearAlert();

            NotifyStart();

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

            try
            {
                while (true)
                {
                    try
                    {
                        var availableSequence = _sequenceBarrier.WaitFor(nextSequence);

                        if (_batchStartAware != null)
                        {
                            _batchStartAware.OnBatchStart(availableSequence - nextSequence + 1);
                        }

                        while (nextSequence <= availableSequence)
                        {
                            evt = _dataProvider[nextSequence];
                            _eventHandler.OnEvent(evt, nextSequence, nextSequence == availableSequence);
                            nextSequence++;
                        }

                        _sequence.SetValue(availableSequence);
                    }
                    catch (TimeoutException)
                    {
                        NotifyTimeout(_sequence.Value);
                    }
                    catch (AlertException)
                    {
                        if (_running == 0)
                        {
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        _exceptionHandler.HandleEventException(ex, nextSequence, evt);
                        _sequence.SetValue(nextSequence);
                        nextSequence++;
                    }
                }
            }
            finally
            {
                NotifyShutdown();
                _running = 0;
            }
        }
示例#2
0
        /// <summary>
        /// Start the worker pool processing events in sequence.
        /// </summary>
        /// <exception cref="InvalidOperationException">if the pool is already started or halted</exception>
        public RingBuffer <T> Start(TaskScheduler taskScheduler)
        {
            var previousRunState = Interlocked.CompareExchange(ref _runState, ProcessorRunStates.Running, ProcessorRunStates.Idle);

            if (previousRunState == ProcessorRunStates.Running)
            {
                throw new InvalidOperationException("WorkerPool is already running");
            }

            if (previousRunState == ProcessorRunStates.Halted)
            {
                throw new InvalidOperationException("WorkerPool is halted and cannot be restarted");
            }

            var cursor = _ringBuffer.Cursor;

            _workSequence.SetValue(cursor);

            foreach (var workProcessor in _workProcessors)
            {
                workProcessor.Sequence.SetValue(cursor);
                workProcessor.Start(taskScheduler);
            }

            return(_ringBuffer);
        }
示例#3
0
        public void Publish(long sequence)
        {
            _cursor.SetValue(sequence);

            if (_isBlockingWaitStrategy)
            {
                _waitStrategy.SignalAllWhenBlocking();
            }
        }
示例#4
0
        private bool HasAvailableCapacity(ISequence[] gatingSequences, int requiredCapacity, long cursorValue)
        {
            var wrapPoint            = (cursorValue + requiredCapacity) - _bufferSize;
            var cachedGatingSequence = _gatingSequenceCache.Value;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue)
            {
                long minSequence = Util.GetMinimumSequence(gatingSequences, cursorValue);
                _gatingSequenceCache.SetValue(minSequence);

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
示例#5
0
        private bool HasAvailableCapacity(int requiredCapacity, long cursorValue)
        {
            var wrapPoint            = (cursorValue + requiredCapacity) - _bufferSize;
            var cachedGatingSequence = _gatingSequenceCache.Value;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue)
            {
                var minSequence = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), cursorValue);
                _gatingSequenceCache.SetValue(minSequence);

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
示例#6
0
        /// <summary>
        /// Start the worker pool processing events in sequence.
        /// </summary>
        /// <returns>the <see cref="RingBuffer{T}"/> used for the work queue.</returns>
        /// <exception cref="InvalidOperationException">if the pool has already been started and not halted yet</exception>
        public RingBuffer <T> Start(IExecutor executor)
        {
            if (Interlocked.Exchange(ref _running, 1) != 0)
            {
                throw new InvalidOperationException("WorkerPool has already been started and cannot be restarted until halted");
            }

            var cursor = _ringBuffer.Cursor;

            _workSequence.SetValue(cursor);

            foreach (var workProcessor in _workProcessors)
            {
                workProcessor.Sequence.SetValue(cursor);
                executor.Execute(workProcessor.Run);
            }

            return(_ringBuffer);
        }
示例#7
0
        private void ProcessEvents()
        {
            var nextSequence = _sequence.Value + 1L;

            while (true)
            {
                try
                {
                    var availableSequence = _sequenceBarrier.WaitFor(nextSequence);

                    _batchStartAware.OnBatchStart(availableSequence - nextSequence + 1);

                    while (nextSequence <= availableSequence)
                    {
                        ref T evt = ref _dataProvider[nextSequence];
                        _eventHandler.OnEvent(ref evt, nextSequence, nextSequence == availableSequence);
                        nextSequence++;
                    }

                    _sequence.SetValue(availableSequence);
                }
示例#8
0
 public void Claim(long sequence)
 {
     _cursor.SetValue(sequence);
 }