internal void Subscribe(IObservableSource <T> source) { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { if (!DisposableHelper.IsDisposed(ref upstream)) { if (source == null) { var o = other; other = null; o.Subscribe(this); } else { var o = source; source = null; o.Subscribe(this); } } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
internal override void Drain() { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { if (DisposableHelper.IsDisposed(ref upstream)) { Interlocked.Exchange(ref sources, null)?.Dispose(); } else { var hasNext = false; var next = default(ICompletableSource); try { if (sources.MoveNext()) { hasNext = true; next = RequireNonNullRef(sources.Current, "The enumerator returned a null ICompletableSource"); } } catch (Exception ex) { DisposableHelper.WeakDispose(ref upstream); ExceptionHelper.AddException(ref errors, ex); ex = Volatile.Read(ref errors); downstream.OnError(ex); continue; } if (hasNext) { next.Subscribe(this); } else { DisposableHelper.WeakDispose(ref upstream); var ex = Volatile.Read(ref errors); if (ex != null) { downstream.OnError(ex); } else { downstream.OnCompleted(); } continue; } } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
internal void Next() { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { if (DisposableHelper.IsDisposed(ref upstream)) { sources?.Dispose(); sources = null; } else { var b = false; var src = default(IObservableSource <T>); try { b = sources.MoveNext(); if (b) { src = ValidationHelper.RequireNonNullRef(sources.Current, "The enumerator returned a null IObservableSource"); } } catch (Exception ex) { DisposableHelper.WeakDispose(ref upstream); downstream.OnError(ex); continue; } if (b) { src.Subscribe(this); } else { DisposableHelper.WeakDispose(ref upstream); var ex = Volatile.Read(ref errors); if (ex != null) { downstream.OnError(ex); } else { downstream.OnCompleted(); } continue; } } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
internal void SetTask(IDisposable d) { if (Interlocked.CompareExchange(ref task, d, null) != null) { if (DisposableHelper.IsDisposed(ref task)) { d.Dispose(); } } }
/// <summary> /// Compose a failure Exception with all relevant state information /// and any Exception(s) received. /// </summary> /// <param name="message">The message to use as prefix to the state</param> /// <returns>The exception to be thrown.</returns> Exception Fail(String message) { var count = Volatile.Read(ref itemCount); var err = Volatile.Read(ref errorCount); var compl = Volatile.Read(ref completions); var timeout = this.timeout; var subs = Volatile.Read(ref upstream) != null; var disposed = DisposableHelper.IsDisposed(ref upstream); var errList = new List <Exception>(); for (int i = 0; i < err; i++) { errList.Add(errors[i]); } var msg = message + " (" + "items=" + count + ", errors=" + err + ", completions=" + compl; if (subs) { msg += ", subscribed!"; } if (timeout) { msg += ", timeout!"; } if (disposed) { msg += ", disposed!"; } if (tag != null) { msg += ", tag=" + tag; } msg += ")"; if (err > 1) { return(new Exception(msg, new AggregateException(errList))); } if (err == 1) { return(new Exception(msg, errList[0])); } return(new Exception(msg)); }
public void OnSuccess(T item) { var en = default(IEnumerator <R>); try { en = RequireNonNullRef(mapper(item).GetEnumerator(), "The GetEnumerator returned a null IEnumerator"); } catch (Exception ex) { OnError(ex); return; } for (; ;) { if (DisposableHelper.IsDisposed(ref upstream)) { en.Dispose(); break; } var v = default(R); var b = false; try { b = en.MoveNext(); if (b) { v = en.Current; } } catch (Exception ex) { en.Dispose(); OnError(ex); break; } if (b) { downstream.OnNext(v); } else { downstream.OnCompleted(); break; } } }
public void OnNext(T item) { if (!DisposableHelper.IsDisposed(ref upstream)) { try { onNext?.Invoke(item); } catch (Exception ex) { upstream.Dispose(); OnError(ex); } } }
public void OnError(Exception ex) { if (!DisposableHelper.IsDisposed(ref upstream)) { DisposableHelper.WeakDispose(ref upstream); try { onError?.Invoke(ex); } catch (Exception) { // TODO where to put these? } } }
public void OnCompleted() { if (!DisposableHelper.IsDisposed(ref upstream)) { DisposableHelper.WeakDispose(ref upstream); try { onCompleted?.Invoke(); } catch (Exception) { // TODO where to put these? } } }
public bool MoveNext() { var q = queue; for (; ;) { if (DisposableHelper.IsDisposed(ref upstream)) { current = default(T); while (q.TryDequeue(out var _)) { ; } return(false); } var d = Volatile.Read(ref done); var empty = !q.TryDequeue(out current); if (d && empty) { DisposableHelper.Dispose(ref upstream); var ex = error; if (ex != null) { throw ex; } return(false); } if (!empty) { Interlocked.Decrement(ref wip); return(true); } if (Volatile.Read(ref wip) == 0) { lock (this) { while (Volatile.Read(ref wip) == 0) { Monitor.Wait(this); } } } } }
internal void Drain(IMaybeSource <T> source) { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { if (!DisposableHelper.IsDisposed(ref upstream)) { if (source != null) { source.Subscribe(this); source = null; } else { var idx = index; if (idx == fallbacks.Length) { DisposableHelper.WeakDispose(ref upstream); downstream.OnCompleted(); } else { var src = fallbacks[idx]; if (src == null) { DisposableHelper.WeakDispose(ref upstream); downstream.OnError(new NullReferenceException("The fallback IMaybeSource at index " + idx + " is null")); } else { index = idx + 1; src.Subscribe(this); } } } } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
internal void Run() { if (DisposableHelper.IsDisposed(ref task)) { return; } if (fused) { var fr = fusedReady; if (fr == end) { downstream.OnCompleted(); Dispose(); } else { Volatile.Write(ref fusedReady, fr + 1); downstream.OnNext(default(long)); if (fr + 1 == end) { downstream.OnCompleted(); Dispose(); } } } else { var idx = index; if (idx == end) { downstream.OnCompleted(); Dispose(); } else { index = idx + 1; downstream.OnNext(idx); if (idx + 1 == end) { downstream.OnCompleted(); Dispose(); } } } }
internal void Drain() { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { if (!DisposableHelper.IsDisposed(ref upstream)) { source.Subscribe(this); } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
/// <summary> /// Trigger the next subscription if there is no active /// subscription currently (<see cref="active"/> is false). /// </summary> internal void Next() { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { if (!DisposableHelper.IsDisposed(ref upstream)) { if (!active) { active = true; source.Subscribe(this); } } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
public bool IsDisposed() { return(DisposableHelper.IsDisposed(ref disposable)); }
void DrainLoop() { var missed = 1; var downstream = this.downstream; for (; ;) { if (!DisposableHelper.IsDisposed(ref upstream)) { if (!delayErrors) { var ex = Volatile.Read(ref errors); if (ex != null) { downstream.OnError(errors); Dispose(); continue; } } var d = Volatile.Read(ref done); var inner = Volatile.Read(ref current); var empty = inner == null; if (d && empty) { var ex = Volatile.Read(ref errors); if (ex != null) { downstream.OnError(errors); } else { downstream.OnCompleted(); } DisposableHelper.Dispose(ref upstream); } else if (!empty) { var state = inner.GetState(); if (state == 1) { downstream.OnNext(inner.value); Interlocked.CompareExchange(ref current, null, current); continue; } else if (state == 2) { Interlocked.CompareExchange(ref current, null, current); continue; } } } missed = Interlocked.Add(ref wip, -missed); if (missed == 0) { break; } } }
internal bool IsDisposed() { return(DisposableHelper.IsDisposed(ref next)); }
internal override void Drain() { if (Interlocked.Increment(ref wip) == 1) { for (; ;) { var srcs = sources; var n = srcs.Length; if (DisposableHelper.IsDisposed(ref upstream)) { for (int i = index; i < n; i++) { srcs[i] = null; } } else { var i = index; if (i == n) { DisposableHelper.WeakDispose(ref upstream); var ex = Volatile.Read(ref errors); if (ex != null) { downstream.OnError(ex); } else { downstream.OnCompleted(); } } else { var src = srcs[i]; if (src == null) { DisposableHelper.WeakDispose(ref upstream); ExceptionHelper.AddException(ref errors, new NullReferenceException("The " + i + "th ICompletableSource is null")); var ex = Volatile.Read(ref errors); downstream.OnError(ex); continue; } else { srcs[i] = null; index = i + 1; src.Subscribe(this); } } } if (Interlocked.Decrement(ref wip) == 0) { break; } } } }
protected bool IsDisposedUpstream() { return(DisposableHelper.IsDisposed(ref upstream)); }
internal bool IsDisposed() { return(DisposableHelper.IsDisposed(ref upstream)); }
internal void Run() { var q = queue; for (; ;) { if (DisposableHelper.IsDisposed(ref upstream)) { while (q.TryDequeue(out var _)) { ; } return; } var d = Volatile.Read(ref done); var empty = !q.TryDequeue(out var v); if (d && empty) { var ex = error; try { if (ex != null) { Error(ex); } else { Completed(); } } finally { Dispose(); } return; } if (!empty) { Interlocked.Decrement(ref wip); var b = false; try { b = Next(v); } catch (Exception ex) { try { Error(ex); } finally { Dispose(); } } if (b) { continue; } else { try { Completed(); } finally { Dispose(); } } } if (Volatile.Read(ref wip) == 0) { lock (this) { while (Volatile.Read(ref wip) == 0) { Monitor.Wait(this); } } } } }
/// <summary> /// Returns true if this subject has been disposed. /// </summary> /// <returns>True if this subject has been disposed</returns> public bool IsDisposed() { return(DisposableHelper.IsDisposed(ref upstream)); }
public bool IsDisposed() { return(DisposableHelper.IsDisposed(ref resource)); }