#pragma once

using namespace System::Threading;


// C# 互換の C++/CLI 用 lock クラス。
//
//「C++/CLI と C# とで同じ Object に排他をかけたい場合」に使用すること。
// （C# の lock も System::Threading::Monitor を使用しているため、このクラスと機能的な互換性がある。）
//
// C++/CLI だけで収束する場合はネイティブ（AutoLock または CritSec）を、
// C# だけで就職する場合は自前の構文（lock）を、それぞれ使用すること。
//
public ref class Lock
{
public:
	Lock( Object^ rObject )
	{
		this->m_rObject = rObject;
		Monitor::Enter( this->m_rObject );
	}
	~Lock()
	{
		if( nullptr != this->m_rObject )
		{
			this->t手放す();
			//delete this->m_rObject;		勝手に delete したらあかんやろ……
			//this->m_rObject = nullptr;
		}

		//GC::SuppressFinalize( this );   --> コンパイラが勝手にやる
	}

	void t取得する()
	{
		if( !Monitor::IsEntered( this->m_rObject ) )
			Monitor::Enter( this->m_rObject );
	}

	void t手放す()
	{
		if( Monitor::IsEntered( this->m_rObject ) )
			Monitor::Exit( this->m_rObject );
	}

private:
	Object^	m_rObject;
};