//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
using System;
using System.Threading;

namespace Benchmark
{
	/// <summary>
	/// Podsumowanie dla WorkComplete.
	/// </summary>
	class WorkComplete
	{
		private int count;
		private ManualResetEvent _lock;
		// Ustawienie początkowego licznika
		public WorkComplete(int count) 
		{
			this.count = count;
			_lock = new ManualResetEvent(false);
		}

		public void Reset(int count)
		{
			lock(this)
			{
				this.count = count;
				_lock.Reset();
			}
		}
		public void P() 
		{
			Monitor.Enter(this);
			if(count > 0) 
			{
				Monitor.Exit(this);
				_lock.WaitOne();
				return;
			}
			Monitor.Exit(this);
		}

		public void V() 
		{
			// Zablokowanie obiektu
			// Zwiększenie o jedną jednostkę semafora
			lock(this)
			{
				count--;
				if(count == 0)
				{
					// Sygnalizacja kolejnego oczekującego wątku
					_lock.Set();
				}
			}
		}
	}
}
