public override bool Poll(ProcessorSubscription ps, out T item) { long e = ps.emitted; if (Volatile.Read(ref size) == e) { item = default(T); return(false); } int offset = ps.offset; var n = ps.node as ArrayNode; var a = n.array; int m = a.Length; if (offset == m) { n = n.next; ps.node = n; a = n.array; offset = 0; } item = a[offset]; ps.offset = offset + 1; ps.emitted = e + 1; return(true); }
/// <summary> /// Subscribe with the relaxed IFlowableSubscriber instance. /// </summary> /// <param name="subscriber">The IFlowableSubscriber instance, not null.</param> public void Subscribe(IFlowableSubscriber<T> subscriber) { ProcessorSubscription ps = new ProcessorSubscription(subscriber, this); subscriber.OnSubscribe(ps); if (Add(ps)) { if (ps.IsCancelled()) { Remove(ps); return; } } else { Exception ex = error; if (ex != null) { ps.OnError(ex); } else { ps.OnComplete(); } } }
/// <summary> /// Subscribe with the relaxed IFlowableSubscriber instance. /// </summary> /// <param name="subscriber">The IFlowableSubscriber instance, not null.</param> public void Subscribe(IFlowableSubscriber <T> subscriber) { var ps = new ProcessorSubscription(subscriber, this); subscriber.OnSubscribe(ps); if (Add(ps)) { if (ps.IsCancelled()) { Remove(ps); } } else { Exception ex = error; if (ex != null) { ps.Error(ex); } else if (hasValue) { ps.Complete(value); } else { ps.Complete(); } } }
public override void ReplayFused(ProcessorSubscription ps) { int missed = 1; ArrayNode n = ps.node as ArrayNode; if (n == null) { n = head; ps.node = n; } for (;;) { if (ps.IsCancelled) { ps.node = Dead; return; } bool d = Volatile.Read(ref done); bool empty = Volatile.Read(ref size) == ps.emitted; if (!empty) { ps.OnNext(default(T)); } if (d) { Exception ex = error; if (ex != null) { ps.OnError(ex); } else { ps.OnComplete(); } return; } int w = Volatile.Read(ref ps.wip); if (w == missed) { missed = Interlocked.Add(ref ps.wip, -missed); if (missed == 0) { break; } } else { missed = w; } } }
public override bool Poll(ProcessorSubscription ps, out T item) { if (ps.node is Node n) { var next = Volatile.Read(ref n.next); if (next != null) { item = next.item; ps.node = next; return(true); } } item = default(T); return(false); }
public void Replay(ProcessorSubscription ps) { if (Interlocked.Increment(ref ps.wip) != 1) { return; } if (ps.outputFused) { ReplayFused(ps); } else { ReplayAsync(ps); } }
public void Subscribe(IFlowableSubscriber <T> subscriber) { ProcessorSubscription ps = new ProcessorSubscription(subscriber, this); subscriber.OnSubscribe(ps); if (Add(ps)) { if (ps.IsCancelled) { Remove(ps); return; } } Replay(ps); }
bool Add(ProcessorSubscription inner) { for (;;) { var a = Volatile.Read(ref subscribers); if (a == Terminated) { return(false); } int n = a.Length; var b = new ProcessorSubscription[n + 1]; Array.Copy(a, 0, b, 0, n); b[n] = inner; if (Interlocked.CompareExchange(ref subscribers, b, a) == a) { return(true); } } }
void Remove(ProcessorSubscription inner) { for (;;) { var a = Volatile.Read(ref subscribers); int n = a.Length; if (n == 0) { break; } int j = -1; for (int i = 0; i < n; i++) { if (a[i] == inner) { j = i; break; } } if (j < 0) { break; } ProcessorSubscription[] b; if (n == 1) { b = Empty; } else { b = new ProcessorSubscription[n - 1]; Array.Copy(a, 0, b, 0, j); Array.Copy(a, j + 1, b, j, n - j - 1); } if (Interlocked.CompareExchange(ref subscribers, b, a) == a) { break; } } }
public override void ReplayAsync(ProcessorSubscription ps) { int missed = 1; long e = ps.emitted; ArrayNode n = ps.node as ArrayNode; int offset = ps.offset; if (n == null) { n = head; } int m = n.array.Length; for (;;) { long r = Volatile.Read(ref ps.requested); while (e != r) { if (ps.IsCancelled) { ps.node = Dead; return; } bool d = Volatile.Read(ref done); bool empty = Volatile.Read(ref size) == e; if (d && empty) { Exception ex = error; if (ex != null) { ps.OnError(ex); } else { ps.OnComplete(); } return; } if (empty) { break; } if (offset == m) { offset = 0; n = n.next; } T v = n.array[offset]; ps.OnNext(v); e++; offset++; } if (e == r) { if (ps.IsCancelled) { return; } if (Volatile.Read(ref done) && Volatile.Read(ref size) == e) { Exception ex = error; if (ex != null) { ps.OnError(ex); } else { ps.OnComplete(); } return; } } int w = Volatile.Read(ref ps.wip); if (w == missed) { ps.emitted = e; ps.offset = offset; ps.node = n; missed = Interlocked.Add(ref ps.wip, -missed); if (missed == 0) { break; } } else { missed = w; } } }
public abstract bool IsEmpty(ProcessorSubscription ps);
public abstract bool Poll(ProcessorSubscription ps, out T item);
public abstract void ReplayFused(ProcessorSubscription ps);
public override void ReplayAsync(ProcessorSubscription ps) { int missed = 1; long e = ps.emitted; var n = ps.node as Node; if (n == null) { n = Volatile.Read(ref head); } for (;;) { long r = Volatile.Read(ref ps.requested); while (e != r) { if (ps.IsCancelled) { ps.node = Dead; return; } bool d = Volatile.Read(ref done); var next = Volatile.Read(ref n.next); bool empty = next == null; if (d && empty) { Exception ex = error; if (ex != null) { ps.OnError(ex); } else { ps.OnComplete(); } return; } if (empty) { break; } ps.OnNext(next.item); e++; n = next; } if (e == r) { if (ps.IsCancelled) { ps.node = Dead; return; } if (Volatile.Read(ref done) && Volatile.Read(ref n.next) == null) { Exception ex = error; if (ex != null) { ps.OnError(ex); } else { ps.OnComplete(); } return; } } int w = Volatile.Read(ref ps.wip); if (w == missed) { ps.emitted = e; ps.node = n; missed = Interlocked.Add(ref ps.wip, -missed); if (missed == 0) { break; } } else { missed = w; } } }
public abstract void ReplayAsync(ProcessorSubscription ps);
public override bool IsEmpty(ProcessorSubscription ps) { var n = ps.node as Node; return(n == null || Volatile.Read(ref n.next) == null); }
public override bool IsEmpty(ProcessorSubscription ps) { return(Volatile.Read(ref size) == ps.emitted); }