Exemple #1
0
        bool Add(AsyncSubjectDisposable inner)
        {
            for (; ;)
            {
                var a = Volatile.Read(ref _observers);
                if (a == DISPOSED)
                {
                    _value     = default(T);
                    _exception = null;
                    ThrowDisposed();
                    return(true);
                }

                if (a == TERMINATED)
                {
                    return(false);
                }

                var n = a.Length;
                var b = new AsyncSubjectDisposable[n + 1];
                Array.Copy(a, 0, b, 0, n);
                b[n] = inner;
                if (Interlocked.CompareExchange(ref _observers, b, a) == a)
                {
                    return(true);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Subscribes an observer to the subject.
        /// </summary>
        /// <param name="observer">Observer to subscribe to the subject.</param>
        /// <returns>Disposable object that can be used to unsubscribe the observer from the subject.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="observer"/> is <c>null</c>.</exception>
        public override IDisposable Subscribe(IObserver <T> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }

            var parent = new AsyncSubjectDisposable(this, observer);

            if (!Add(parent))
            {
                var ex = _exception;
                if (ex != null)
                {
                    observer.OnError(ex);
                }
                else
                {
                    if (_hasValue)
                    {
                        observer.OnNext(_value);
                    }
                    observer.OnCompleted();
                }
                return(Disposable.Empty);
            }

            return(parent);
        }
Exemple #3
0
        void Remove(AsyncSubjectDisposable inner)
        {
            for (; ;)
            {
                var a = Volatile.Read(ref _observers);

                var n = a.Length;

                if (n == 0)
                {
                    break;
                }

                var j = -1;

                for (var i = 0; i < n; i++)
                {
                    if (a[i] == inner)
                    {
                        j = i;
                        break;
                    }
                }

                if (j < 0)
                {
                    break;
                }

                var b = default(AsyncSubjectDisposable[]);
                if (n == 1)
                {
                    b = EMPTY;
                }
                else
                {
                    b = new AsyncSubjectDisposable[n - 1];
                    Array.Copy(a, 0, b, 0, j);
                    Array.Copy(a, j + 1, b, j, n - j - 1);
                }

                if (Interlocked.CompareExchange(ref _observers, b, a) == a)
                {
                    break;
                }
            }
        }