using System;
using System.Collections.Generic;
using System.Threading;

namespace System.Reactive.Subjects
{
	internal sealed class FastImmediateObserver<T> : Interface3<T>, IObserver<T>, IDisposable
	{
		public FastImmediateObserver(IObserver<T> observer)
		{
			this._observer = observer;
		}

		public void Dispose()
		{
			this.Done();
		}

		public void EnsureActive()
		{
			this.EnsureActive(1);
		}

		public void EnsureActive(int count)
		{
			bool flag = false;
			object obj = this._gate;
			lock (obj)
			{
				if (!this._hasFaulted && !this._busy)
				{
					flag = true;
					this._busy = true;
				}
			}
			if (flag)
			{
				for (;;)
				{
					Queue<T> queue = null;
					Exception ex = null;
					bool flag3 = false;
					obj = this._gate;
					lock (obj)
					{
						if (this._queue.Count > 0)
						{
							if (this._queue2 == null)
							{
								this._queue2 = new Queue<T>();
							}
							queue = this._queue;
							this._queue = this._queue2;
							this._queue2 = null;
						}
						if (this._error != null)
						{
							ex = this._error;
						}
						else if (this._done)
						{
							flag3 = true;
						}
						else if (queue == null)
						{
							this._busy = false;
							break;
						}
					}
					try
					{
						IL_00D5:
						if (queue != null)
						{
							while (queue.Count > 0)
							{
								this._observer.OnNext(queue.Dequeue());
							}
							obj = this._gate;
							lock (obj)
							{
								this._queue2 = queue;
							}
						}
						if (ex != null)
						{
							this.Done().OnError(ex);
							break;
						}
						if (flag3)
						{
							this.Done().OnCompleted();
							break;
						}
						continue;
					}
					catch
					{
						obj = this._gate;
						lock (obj)
						{
							this._hasFaulted = true;
							this._queue.Clear();
						}
						throw;
					}
					goto IL_00D5;
				}
			}
		}

		public void OnCompleted()
		{
			object gate = this._gate;
			lock (gate)
			{
				if (!this._hasFaulted)
				{
					this._done = true;
				}
			}
		}

		public void OnError(Exception error)
		{
			object gate = this._gate;
			lock (gate)
			{
				if (!this._hasFaulted)
				{
					this._error = error;
				}
			}
		}

		public void OnNext(T value)
		{
			object gate = this._gate;
			lock (gate)
			{
				if (!this._hasFaulted)
				{
					this._queue.Enqueue(value);
				}
			}
		}

		private IObserver<T> Done()
		{
			return Interlocked.Exchange<IObserver<T>>(ref this._observer, NopObserver<T>.Instance);
		}

		private readonly object _gate = new object();

		private volatile IObserver<T> _observer;

		private Queue<T> _queue = new Queue<T>();

		private Queue<T> _queue2;

		private Exception _error;

		private bool _done;

		private bool _busy;

		private bool _hasFaulted;
	}
}
