Windows版iTRONサービスコールの作成 (タスク管理)
(その12)

強制待ち状態からのタスクを再開する

強制待ち(サスペンド)状態からのタスクを再開するサービスコールは以下のとおりです。

rsm_tsk()によるタスクの再開(レジューム)は、sus_tsk()(サスペンド)を呼び出した回数分レジュームを呼び出さないとタスクの起動は再開されません。

frsm_tsk()による強制的な再開は、sus_tsk()の呼び出し回数にかかわらず1回のの呼び出しでタスクの起動を再開します。


サービスコール名説明
rsm_tsk

強制待ち状態からのタスクを再開します。

frsm_tsk

強制待ち状態からのタスクを強制的に再開します。

※ Ver3.0、Ver4.0共に同じサービスコールの形式です。

強制待ち状態からのタスクを再開する

sus_tsk()によって強制待ち状態になったタスクの実行を再開させます。

sus_tsk()を呼び出した回数と同じ回数だけrsm_tsk()を呼び出さないとタスクの強制待ち状態は解除されません。


強制待ち状態からのタスクを再開するには以下のサービスコールを使用します。


    ER rsm_tsk( ID tskid )
	

引数説明
tskid

タスクID番号。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のタスクID番号。

E_NOEXS

指定したタスクID番号のタスクが未登録。

E_OBJ

タスクが強制待ち状態でない。


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


/****************************************************************************/
/*!
 *  @brief  強制待ち状態からの再開.
 *
 *  @param  [in]    tskid   タスクID番号.
 *
 *  @retval エラーコード.
 */
ER      rsm_tsk( ID tskid )
{
    ER ercd;

    wi_CommonLock();

    //! タスクを待ち状態から再開する.
    ercd = wi_ResumeTask( tskid );

    wi_CommonUnlock();
    return ercd;
}
	

タスクID番号を引数にしてタスクのレジューム関数を呼び出します。

タスクのレジューム関数

タスクのレジューム関数のソースコードは以下のとおりです。



/****************************************************************************/
/*!
 *  @brief  強制待ち状態からの再開.
 *
 *  @param  [in]    id      タスクID番号.
 *
 *  @retval エラーコード.
 */
ER      wi_ResumeTask( INT id )
{
    DWORD       cnt;
    ER          ercd;
    WITSKOBJ    *p;

    //! タスクIDのオブジェクトを取得する.
    p = FindTaskObject( id, &ercd );
    if( !p ){
        return ercd;
    }
    if( !p->hThread ){
        return E_OBJ;
    }
    //! スレッドの実行を再開する.
    cnt = ResumeThread( p->hThread );
    if( cnt == -1 ){
        return E_SYS;
    }
    //! スレッドが再開するときにステータスを「タスク実行中」に戻す.
    if( cnt == 1 ){
        if( p->EventType == 0 ){
            p->TaskState = TTS_RUN;
        }else{
            p->TaskState = TTS_WAI;
        }
    }
    //! スレッドが中断していなかった場合はエラーにする.
    if( cnt == 0 ){
        p->SuspendCnt = 0;
        return E_OBJ;
    }
    //! スレッドの中断カウンタを-1する.
    p->SuspendCnt = cnt - 1;
    return E_OK;
}
	

タスクをレジュームする関数は以下のような処理を行います。

  • 引数で指定されたタスクID番号に該当するタスク・オブジェクトを取り出します。
  • スレッドの実行を再開します。
  • ResumeThread()の戻り値が 1未満の場合、タスクはレジューム状態ではなかったのでエラー終了にします。
  • スレッドの中断カウンタを -1 して処理を終了します。

実行を中断しているスレッドを起動するには ResumeThread() を呼び出します。


    DWORD ResumeThread( HANDLE hThread )
	

引数説明
hThread

スレッドのハンドル。

戻り値説明
2以上

スレッドは依然として中断しています。

1

中断していたスレッドが再開されました。

0

スレッドは中断していませんでした。

-1

関数の呼び出しに失敗しました。


強制待ち状態からのタスクを強制的に再開する

sus_tsk()によって強制待ち状態になったタスクの実行を再開させます。

sus_tsk()を呼び出した回数に関係なくfrsm_tsk()を呼び出すとタスクの強制待ち状態は解除されます。


強制待ち状態からのタスクを強制的に再開するには以下のサービスコールを使用します。


    ER frsm_tsk( ID tskid )
	

引数説明
tskid

タスクID番号。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のタスクID番号。

E_NOEXS

指定したタスクID番号のタスクが未登録。

E_OBJ

タスクが強制待ち状態でない。


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


/****************************************************************************/
/*!
 *  @brief  強制待ち状態からの強制再開.
 *
 *  @param  [in]    tskid   タスクID番号.
 *
 *  @retval エラーコード.
 */
ER      frsm_tsk( ID tskid )
{
    ER ercd;

    wi_CommonLock();

    //! 強制待ちをしているタスクを強制的に再開させる.
    ercd = wi_ForceResumeTask( tskid );

    wi_CommonUnlock();
    return ercd;
}
	

タスクID番号を引数にして、タスクの強制レジューム関数を呼び出します。

タスクの強制レジューム関数

タスクの強制レジューム関数のソースコードは以下のとおりです。



/****************************************************************************/
/*!
 *  @brief  強制待ち状態からの強制再開.
 *
 *  @param  [in]    id      タスクID番号.
 *
 *  @retval エラーコード.
 */
ER      wi_ForceResumeTask( INT id )
{
    DWORD       cnt;
    ER          ercd;
    WITSKOBJ    *p;

    //! タスクIDのオブジェクトを取得する.
    p = FindTaskObject( id, &ercd );
    if( !p ){
        return ercd;
    }
    if( !p->hThread ){
        return E_OBJ;
    }
    //! スレッドのレジューム状態が解除されるまで繰り返す.
    do {
        cnt = ResumeThread( p->hThread );
    } while( cnt > 1 );

    if( cnt == -1 ){
        return E_SYS;
    }
    //! スレッドが再開するときにステータスを「タスク実行中」に戻す.
    if( p->EventType == 0 ){
        p->TaskState = TTS_RUN;
    }else{
        p->TaskState = TTS_WAI;
    }
    //! スレッドの中断カウンタをクリアする.
    p->SuspendCnt = 0;
    return E_OK;
}
	

タスクを強制レジュームする関数は以下のような処理を行います。

  • 引数で指定されたタスクID番号に該当するタスク・オブジェクトを取り出します。
  • ResumeThread()の戻り値が 1未満になるまで繰り返し呼び出します。
  • ResumeThread()の戻り値が-1の場合はエラー終了にします。
  • スレッドの中断カウンタを 0 にクリアして処理を終了します。


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