private void CheckOnlyStartedOnce() { if (!started.AtomicCompareExchange(true, false)) { throw new InvalidOperationException("Disruptor.Start() must only be called once."); } }
public void Run() { if (!running.AtomicCompareExchange(true, false)) { throw new Exception("AtomicCompareExchange Exception"); } }
public void Run() { if (!isRunning.AtomicCompareExchange(true, false)) { throw new Exception("Already running"); } foreach (ISequenceBarrier barrier in barriers) { barrier.ClearAlert(); } int barrierLength = barriers.Length; //????????????????????? //long[] lastConsumed = new long[barrierLength]; //fill(lastConsumed, -1L); //Array.CreateInstance(typeof(long),barrierLength); while (true) { try { for (int i = 0; i < barrierLength; i++) { long available = barriers[i].WaitFor(-1); Sequence sequence = sequences[i]; long previous = sequence.Value; for (long l = previous + 1; l <= available; l++) { handler.OnEvent(providers[i].Get(l), l, previous == available); } sequence.Value = available; count += (available - previous); } Thread.Yield(); } catch (AlertException e) { if (!isRunning.ReadFullFence()) { break; } } catch (Disruptor.TimeoutException e) { Console.WriteLine(e.ToString()); } catch (Exception e) { Console.WriteLine(e.ToString()); break; } } }
private void WaitForAndSetFlag(bool newValue) { while (!stopped && Thread.CurrentThread.IsAlive && !readyToProcessEvent.AtomicCompareExchange(!newValue, newValue)) { Thread.Sleep(0); } }
/// <summary> /// It is ok to have another thread rerun this method after a halt(). /// </summary> public void Run() { if (!running.AtomicCompareExchange(true, false)) { throw new InvalidOperationException("Thread is already running"); } sequenceBarrier.ClearAlert(); NotifyStart(); T @event = null; var nextSequence = sequence.Value + 1L; try { while (true) { try { var availableSequence = sequenceBarrier.WaitFor(nextSequence); ///availableSequence=-1 ?????????? while (nextSequence <= availableSequence) { @event = dataProvider.Get(nextSequence); eventHandler.OnEvent(@event, nextSequence, nextSequence == availableSequence); nextSequence++; } sequence.LazySet(availableSequence); //sequence.Value = availableSequence; } catch (TimeoutException e) { NotifyTimeout(sequence.Value); } catch (AlertException ex) { if (!running.ReadFullFence()) { break; } } catch (Exception ex) { exceptionHandler.HandleEventException(ex, nextSequence, @event); sequence.LazySet(nextSequence); //sequence.Value = nextSequence; nextSequence++; } } } finally { NotifyShutdown(); running.WriteFullFence(false); } }
/// <summary> /// Start the worker pool processing events in sequence. /// </summary> /// <param name="taskScheduler"> the <see cref="TaskScheduler"/> used to start <see cref="IEventProcessor"/>s.</param> /// <returns>the <see cref="RingBuffer"/> used for the work queue.</returns> public RingBuffer <T> start(TaskScheduler taskScheduler) { if (!started.AtomicCompareExchange(true, false)) { throw new InvalidOperationException("WorkerPool has already been started and cannot be restarted until halted."); } var cursor = ringBuffer.GetCursor; workSequence.Value = cursor; foreach (var processor in workProcessors) { processor.Sequence.Value = cursor; Task.Factory.StartNew(processor.Run, CancellationToken.None, TaskCreationOptions.None, taskScheduler); } return(ringBuffer); }
public void SignalAllWhenBlocking() { if (signalNeeded.AtomicCompareExchange(false, true)) { bool lockToken = false; Monitor.Enter(obj, ref lockToken); try { Monitor.Pulse(obj); } finally { if (lockToken) { Monitor.Exit(obj); } } } }
public void AtomicCompareExchangeReturnsTrueIfComparandEqualsCurrentValue() { Assert.IsTrue(_volatile.AtomicCompareExchange(NewValue, InitialValue)); }