Windows版 iTRONサービスコールの作成 (ランデブポート)
(その5)

ランデブの受け付け

ランデブを受け付けるサービスコールは以下のとおりです。


サービスコール名説明
acp_por

タイムアウトなしでランデブを受け付けます。

pacp_por

ポーリング方式でランデブを受け付けます。

tacp_por

タイムアウト付きでランデブを受け付けます。

※ Ver3.0と4.0では関数名は同じですが、引数が異なりますので注意してください。

ランデブを受け付ける (タイムアウトなし)

タイムアウトなしでランデブを受け付けるには以下のサービスコールを使用します。


・Ver3.0の場合


    ER acp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
	

引数説明
p_rdvno

ランデブ番号を格納する領域のポインタ。

msg

呼び出しメッセージを格納する領域のポインタ。

p_cmsgsz

呼び出しメッセージのサイズを格納する領域のポインタ。

porid

ランデブポートID番号。

acpptn

受け付け側選択条件のビットパターン。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のランデブポートID番号。

E_NOEXS

指定したランデブポートID番号は登録されていない。

E_PAR

パラメータエラー。

E_CTX

非コンテキスト・タスクからの呼び出し。


・Ver4.0の場合


    ER_UINT acp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
	

引数説明
porid

ランデブポートID番号。

acpptn

受け付け側選択条件のビットパターン。

p_rdvno

ランデブ番号を格納する領域のポインタ。

msg

呼び出しメッセージを格納する領域のポインタ。

戻り値説明
E_ID

範囲外のランデブポートID番号。

E_NOEXS

指定したランデブポートID番号は登録されていない。

E_PAR

パラメータエラー。

E_CTX

非コンテキスト・タスクからの呼び出し。

その他の正数

呼び出しメッセージのサイズ。


・Ver3.0のサービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け (タイムアウトなし).
 *
 *  @param  [out]   p_rdvno     ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *  @param  [out]   p_cmsgsz    呼び出しメッセージのサイズを格納する領域のポインタ.
 *  @param  [in]    porid       ランデブポートID番号.
 *  @param  [in]    acpptn      受け付け側選択条件のビットパターン.
 *
 *  @retval エラーコード.
 */
ER      acp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
{
    //! タイムアウトなしでランデブを受け付ける.
    return tacp_por( p_rdvno, msg, p_cmsgsz, porid, acpptn, TMO_FEVR );
}
	


・Ver4.0のサービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け (タイムアウトなし).
 *
 *  @param  [in]    porid       ランデブポートID番号.
 *  @param  [in]    acpptn      受け付け側選択条件のビットパターン.
 *  @param  [out]   p_rdvno     ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *
 *  @retval 呼び出しメッセージのサイズまたはエラーコード.
 */
ER_UINT acp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
{
    //! タイムアウトなしでランデブを受け付ける.
    return tacp_por( porid, acpptn, p_rdvno, msg, TMO_FEVR );
}
	

tacp_por()のタイムアウト設定に TMO_FEVR を指定して呼び出します。

ランデブが成立しない場合は、ランデブが成立するまでタスクをスリープさせます。

ランデブを受け付ける (ポーリング)

ポーリングでランデブを受け付けるには以下のサービスコールを使用します。


・Ver3.0の場合


    ER pacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
	

引数説明
p_rdvno

ランデブ番号を格納する領域のポインタ。

msg

呼び出しメッセージを格納する領域のポインタ。

p_cmsgsz

呼び出しメッセージのサイズを格納する領域のポインタ。

porid

ランデブポートID番号。

acpptn

受け付け側選択条件のビットパターン。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のランデブポートID番号。

E_NOEXS

指定したランデブポートID番号は登録されていない。

E_PAR

パラメータエラー。

E_CTX

非コンテキスト・タスクからの呼び出し。

E_TMOUT

ランデブが成立しない。


・Ver4.0の場合


    ER_UINT pacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
	

引数説明
porid

ランデブポートID番号。

acpptn

受け付け側選択条件のビットパターン。

p_rdvno

ランデブ番号を格納する領域のポインタ。

msg

呼び出しメッセージを格納する領域のポインタ。

戻り値説明
E_ID

範囲外のランデブポートID番号。

E_NOEXS

指定したランデブポートID番号は登録されていない。

E_PAR

パラメータエラー。

E_CTX

非コンテキスト・タスクからの呼び出し。

E_TMOUT

ランデブが成立しない。

その他の正数

呼び出しメッセージのサイズ。


・Ver3.0のサービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け (ポーリング).
 *
 *  @param  [out]   p_rdvno     ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *  @param  [out]   p_cmsgsz    呼び出しメッセージのサイズを格納する領域のポインタ.
 *  @param  [in]    porid       ランデブポートID番号.
 *  @param  [in]    acpptn      受け付け側選択条件のビットパターン.
 *
 *  @retval エラーコード.
 */
ER      pacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
{
    //! 呼び出し待ちなしでランデブを受け付ける.
    return tacp_por( p_rdvno, msg, p_cmsgsz, porid, acpptn, TMO_POL );
}
	


・Ver4.0のサービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け (ポーリング).
 *
 *  @param  [in]    porid       ランデブポートID番号.
 *  @param  [in]    acpptn      受け付け側選択条件のビットパターン.
 *  @param  [out]   p_rdvno     ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *
 *  @retval 呼び出しメッセージのサイズまたはエラーコード.
 */
ER_UINT pacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
{
    //! 呼び出し待ちなしでランデブを受け付ける.
    return tacp_por( porid, acpptn, p_rdvno, msg, TMO_POL );
}
	

tacp_por()のタイムアウト設定に TMO_POL を指定して呼び出します。

ランデブが成立しない場合は、タスクをスリープさせずに戻り値をE_TMOUTとしてすぐにサービスコールから戻ります。

ランデブを受け付ける (タイムアウト付き)

タイムアウト付きでランデブを受け付けるには以下のサービスコールを使用します。


・Ver3.0の場合


    ER tacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn, TMO tmout )
	

引数説明
p_rdvno

ランデブ番号を格納する領域のポインタ。

msg

呼び出しメッセージを格納する領域のポインタ。

p_cmsgsz

呼び出しメッセージのサイズを格納する領域のポインタ。

porid

ランデブポートID番号。

acpptn

受け付け側選択条件のビットパターン。

tmout

タイムアウトの設定値。

  • TMO_FEVRの場合、永久にランデブが成立するのを待ちます。
  • TMO_POLの場合、ランデブが成立しなくてもタスクをスリープしません。
  • その他の正数はタイムアウト値となります。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のランデブポートID番号。

E_NOEXS

指定したランデブポートID番号は登録されていない。

E_PAR

パラメータエラー。

E_CTX

非コンテキスト・タスクからの呼び出し。

E_TMOUT

ランデブが成立しない。


・Ver4.0の場合


    ER_UINT tacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg, TMO tmout )
	

引数説明
porid

ランデブポートID番号。

acpptn

受け付け側選択条件のビットパターン。

p_rdvno

ランデブ番号を格納する領域のポインタ。

msg

呼び出しメッセージを格納する領域のポインタ。

tmout

タイムアウトの設定値。

  • TMO_FEVRの場合、永久にランデブが成立するのを待ちます。
  • TMO_POLの場合、ランデブが成立しなくてもタスクをスリープしません。
  • その他の正数はタイムアウト値となります。

戻り値説明
E_ID

範囲外のランデブポートID番号。

E_NOEXS

指定したランデブポートID番号は登録されていない。

E_PAR

パラメータエラー。

E_CTX

非コンテキスト・タスクからの呼び出し。

E_TMOUT

ランデブが成立しない。

その他の正数

応答メッセージのサイズ。


・Ver3.0のサービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け (タイムアウトあり).
 *
 *  @param  [out]   p_rdvno     ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *  @param  [out]   p_cmsgsz    呼び出しメッセージのサイズを格納する領域のポインタ.
 *  @param  [in]    porid       ランデブポートID番号.
 *  @param  [in]    acpptn      受け付け側選択条件のビットパターン.
 *  @param  [in]    tmout       タイムアウト設定.
 *
 *  @retval エラーコード.
 */
ER      tacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn, TMO tmout )
{
    ER ercd;

    wi_CommonLock();

    //! ランデブを受け付ける.
    ercd = wi_AcceptRendPort( porid, acpptn, p_rdvno, msg, p_cmsgsz, tmout );

    wi_CommonUnlock();
    return ercd;
}
	


・Ver4.0のサービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け (タイムアウトあり).
 *
 *  @param  [in]    porid       ランデブポートID番号.
 *  @param  [in]    acpptn      受け付け側選択条件のビットパターン.
 *  @param  [out]   p_rdvno     ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *  @param  [in]    tmout       タイムアウト設定.
 *
 *  @retval 呼び出しメッセージのサイズまたはエラーコード.
 */
ER_UINT tacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg, TMO tmout )
{
    ER  ercd;
    INT size;

    wi_CommonLock();

    //! ランデブを受け付ける.
    ercd = wi_AcceptRendPort( porid, acpptn, p_rdvno, msg, &size, tmout );
    if( ercd == E_OK ){
        ercd  = size;
    }
    wi_CommonUnlock();
    return ercd;
}
	

指定したランデブポートID番号のランデブを受け付けます。

ランデブが成立しない場合は、ランデブが成立するか、または、タイムアウトで設定した時間が経過するまでタスクをスリープさせます。

ランデブの受け付け関数

ランデブの受け付け関数のソースコードは以下のとおりです。



/****************************************************************************/
/*!
 *  @brief  ランデブ受け付け.
 *
 *  @param  [in]    id          ランデブポートID番号.
 *  @param  [in]    ptn         受け付け側選択条件のビットパターン.
 *  @param  [out]   no          ランデブ番号を格納する領域のポインタ.
 *  @param  [out]   msg         呼び出しメッセージを格納する領域のポインタ.
 *  @param  [out]   size        呼び出しメッセージのサイズを格納する領域のポインタ.
 *  @param  [in]    tmout       タイムアウト設定.
 *
 *  @retval エラーコード.
 */
ER      wi_AcceptRendPort( INT id, UINT ptn, INT *no, VP msg, INT *size, TMO tmout )
{
    ER          ercd;
    WIPOROBJ    *p;
    WITSKOBJ    *cal_tsk,*acp_tsk;

    //! 引数が不正な場合はエラーにする.
    if( !no || !size ){
        return E_PAR;
    }
    //! ランデブポートIDのオブジェクトを取得する.
    p = (WIPOROBJ *)wi_FindObject( id, TMAX_MAXPOR, PortList, &ercd );
    if( !p ){
        return ercd;
    }
    //! 自タスクのタスクコンテキストを取り出す.
    acp_tsk = wi_GetTaskObject( TSK_SELF );
    if( !acp_tsk ){
        return E_CTX;
    }
    acp_tsk->Param[0] = (VP)ptn;
    acp_tsk->Param[1] = (VP)msg;
    acp_tsk->Param[2] = (VP)0;

    //! ランデブ呼び出しをしているタスクに対してランデブが成立するかどうかを調べる.
    cal_tsk = SatisfyRendezvous( (WITSKOBJ *)(p->CalWaitQue), ptn );

    if( !cal_tsk ){
        //! ランデブが成立するまでタスクをスリープさせる.
        ercd = wi_TaskWait( id, TTW_ACP, tmout, p->Attribute, &(p->AcpWaitQue) );
        if( ercd != E_OK ){
            return ercd;
        }
        *size = (INT)acp_tsk->Param[2];
        *no   = (INT)acp_tsk->Param[3];
    }else{
        //! 成立したランデブを登録する.
        ercd = CreateRdv( cal_tsk->Hdr.Id, p->MaxRepMsg );
        if( ercd != E_OK ){
            return ercd;
        }
        //! ランデブ番号を戻り値にセットする.
        *no = RdvSeqNo;

        //! 呼び出しメッセージを呼び出し側タスクからコピーする.
        if( cal_tsk->Param[1] && (INT)cal_tsk->Param[2] > 0 ){
            memcpy( msg, cal_tsk->Param[1], (INT)cal_tsk->Param[2] );
            *size = (INT)cal_tsk->Param[2];
        }else{
            *size = 0;
        }
        //! 呼び出し側タスクを待ち行列から削除する.
        p->CalWaitQue = wi_DelWaitTaskList( cal_tsk->Hdr.Id, p->CalWaitQue );

        //! 呼び出し側タスクのイベント待ち状態を「ランデブ終了待ち」にする.
        cal_tsk->EventType = TTW_RDV;
        cal_tsk->WaitId    = RdvSeqNo;
        cal_tsk->QueLink   = NULL;

        ercd = E_OK;
    }
    return ercd;
}
	

ランデブの受け付け関数は以下のような処理を行います。

  • 引数で指定されたランデブポートID番号に該当するランデブポート・オブジェクトを取り出します。
  • 非タスクコンテキストからの呼び出しの場合はエラー終了します。
  • ランデブ成立待ちをしているタスクがある場合、ランデブ条件ビットパターンをチェックして、ランデブが成立するかどうかを調べます。
  • ランデブが成立しない場合、タスクをスリープさせます。(以降ランデブ成立のチェックは、ランデブ呼び出し側で行います。)
  • ランデブが成立した場合、以下の処理を行います。
    1. 『ランデブ・オブジェクト』を生成します。
    2. ランデブ呼び出しタスクからランデブ呼び出しメッセージをコピーします。
    3. ランデブ呼び出しタスクを待ち行列から削除します。
    4. ランデブ呼び出しタスクのイベント待ち状態を「ランデブ成立待ち」から「ランデブ終了待ち」に変更します。


Windowsは米国Microsoft Corporationの登録商標です。