public virtual void OnSubscribe(IDisposable d)
 {
     this.upstream = d;
     if (d is IFuseableDisposable <T> f)
     {
         this.queue = f;
     }
     downstream.OnSubscribe(this);
 }
Пример #2
0
        /// <summary>
        /// Called at most once with the upstream's IDisposable instance.
        /// Further calls will dispose the IDisposable provided.
        /// </summary>
        /// <param name="d">The upstream's IDisposable instance.</param>
        public virtual void OnSubscribe(IDisposable d)
        {
            if (Interlocked.CompareExchange(ref this.upstream, d, null) != null)
            {
                d?.Dispose();
            }
            else
            {
                if (fusionRequested > FusionSupport.None)
                {
                    if (d is IFuseableDisposable <T> fd)
                    {
                        queue             = fd;
                        fusionEstablished = fd.RequestFusion(fusionRequested);

                        if (fusionEstablished == FusionSupport.Sync)
                        {
                            for (; ;)
                            {
                                if (IsDisposed())
                                {
                                    break;
                                }
                                var v       = default(T);
                                var success = false;
                                try
                                {
                                    v = queue.TryPoll(out success);
                                }
                                catch (Exception ex)
                                {
                                    Dispose();
                                    OnError(ex);
                                    break;
                                }

                                if (!success)
                                {
                                    OnCompleted();
                                    break;
                                }

                                items.Add(v);
                                Volatile.Write(ref itemCount, items.Count);
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
            public void OnSubscribe(IDisposable d)
            {
                upstream = d as IFuseableDisposable <T>;

                if (upstream != null)
                {
                    try
                    {
                        var m = upstream.RequestFusion(boundary ? FusionSupport.AnyBoundary : FusionSupport.Any);
                        if (m != FusionSupport.None)
                        {
                            upstream.IsEmpty();

                            upstream.TryPoll(out var _);

                            upstream.Clear();

                            upstream.IsEmpty();

                            upstream.TryPoll(out var _);

                            try
                            {
                                upstream.TryOffer(default(T));
                            }
                            catch (InvalidOperationException)
                            {
                                // expected
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        error = ex;
                    }
                }
                else
                {
                    error = new Exception("Upstream not fuseable");
                }
            }