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;
                        }
                    }
                }
            }
Exemple #2
0
            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;
                        }
                    }
                }
            }
Exemple #4
0
 internal void SetTask(IDisposable d)
 {
     if (Interlocked.CompareExchange(ref task, d, null) != null)
     {
         if (DisposableHelper.IsDisposed(ref task))
         {
             d.Dispose();
         }
     }
 }
Exemple #5
0
        /// <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;
                    }
                }
            }
Exemple #7
0
 public void OnNext(T item)
 {
     if (!DisposableHelper.IsDisposed(ref upstream))
     {
         try
         {
             onNext?.Invoke(item);
         }
         catch (Exception ex)
         {
             upstream.Dispose();
             OnError(ex);
         }
     }
 }
Exemple #8
0
 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?
         }
     }
 }
Exemple #9
0
 public void OnCompleted()
 {
     if (!DisposableHelper.IsDisposed(ref upstream))
     {
         DisposableHelper.WeakDispose(ref upstream);
         try
         {
             onCompleted?.Invoke();
         }
         catch (Exception)
         {
             // TODO where to put these?
         }
     }
 }
Exemple #10
0
            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();
                        }
                    }
                }
            }
Exemple #13
0
        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));
 }
Exemple #18
0
            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));
 }