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