// <summary>ソースコード：>ＨＹＳＳＯＰセマフォクラス</summary>
// <author>CommonMP</author>

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

using CommonMP.HYSSOP.CoreImpl.HSData;

namespace CommonMP.HYSSOP.CoreImpl.HSTools
{
    /// <summary><para>class outline:</para>
    /// <para>セマフォクラス</para>
    /// </summary>
    /// <remarks>
    /// <para>リソースまたはリソースのプールに同時にアクセスできるスレッドの数を制限</para>
    /// <para>各言語の文法の違いを隠蔽</para>
    /// <para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    public class HySSemaphore
    {
        /// <summary>セマフォクラス</summary>
        protected Semaphore m_csSemaphore;

        /// <summary><para>method outline:</para>
        /// <para>デストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>無し</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>メモリーリーク防止の為　内部変数は必ず null にセットする</para>
        /// </remarks>
        ~HySSemaphore()
        {
            //m_csSemaphore = null;  // <-- m_csSemaphoreをNULL化すると動作がおかしくなる（なぜか？）
        }

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSemaphore csSemaphore = new HySSemaphore(lIni, lMax) </para>
        /// </example>
        /// <param name="lIni">セマフォ初期数</param>
        /// <param name="lMax">セマフォ最大数</param>
        /// <returns>HySSemaphore  生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySSemaphore(long lIni, long lMax)
        {
            m_csSemaphore = new Semaphore((int)lIni, (int)lMax);
        }

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSemaphore csSemaphore = new HySSemaphore(csName, lIni, lMax) </para>
        /// </example>
        /// <param name="csName">セマフォオブジェクト名称</param>
        /// <param name="lIni">セマフォ初期数</param>
        /// <param name="lMax">セマフォ最大数</param>
        /// <returns>HySSemaphore  生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySSemaphore(HySString csName, long lIni, long lMax)
        {
            m_csSemaphore = new Semaphore((int)lIni, (int)lMax, csName.ToString());
        }

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSemaphore csSemaphore = new HySSemaphore(sName, lIni, lMax) </para>
        /// </example>
        /// <param name="sName">セマフォオブジェクト名称</param>
        /// <param name="lIni">セマフォ初期数</param>
        /// <param name="lMax">セマフォ最大数</param>
        /// <returns>HySSemaphore  生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        internal HySSemaphore(string sName, long lIni, long lMax)
        {
            m_csSemaphore = new Semaphore((int)lIni, (int)lMax, sName);
        }

        /// <summary><para>method outline:</para>
        /// <para>セマフォの取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Wait() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>セマフォに入る</para>
        /// </remarks>
        public void Wait()
        {
            // 現在の WaitHandle が信号を受信するまで、現在のスレッドをブロックします
            m_csSemaphore.WaitOne();
        }

        /// <summary><para>method outline:</para>
        /// <para>セマフォの解放</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Release() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>セマフォから出る</para>
        /// </remarks>
        public void Release()
        {
            m_csSemaphore.Release();
        }

        /// <summary><para>method outline:</para>
        /// <para>指定数セマフォの解放</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Release(lNum) </para>
        /// </example>
        /// <param name="lNum">リリース回数</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>1 回の呼び出しで引数分開放される</para>
        /// </remarks>
        public void Release(long lNum)
        {
            m_csSemaphore.Release((int)lNum);
        }
    }
}
