using System;
using System.Threading;

namespace System.Reactive
{
	internal sealed class CheckedObserver<T> : IObserver<T>
	{
		public CheckedObserver(IObserver<T> observer)
		{
			this._observer = observer;
		}

		public void OnNext(T value)
		{
			this.CheckAccess();
			try
			{
				this._observer.OnNext(value);
			}
			finally
			{
				Interlocked.Exchange(ref this._state, 0);
			}
		}

		public void OnError(Exception error)
		{
			this.CheckAccess();
			try
			{
				this._observer.OnError(error);
			}
			finally
			{
				Interlocked.Exchange(ref this._state, 2);
			}
		}

		public void OnCompleted()
		{
			this.CheckAccess();
			try
			{
				this._observer.OnCompleted();
			}
			finally
			{
				Interlocked.Exchange(ref this._state, 2);
			}
		}

		private void CheckAccess()
		{
			int num = Interlocked.CompareExchange(ref this._state, 1, 0);
			if (num == 1)
			{
				throw new InvalidOperationException(Strings_Core.REENTRANCY_DETECTED);
			}
			if (num != 2)
			{
				return;
			}
			throw new InvalidOperationException(Strings_Core.OBSERVER_TERMINATED);
		}

		private readonly IObserver<T> _observer;

		private int _state;
	}
}
