cciRegisterForThreadStateChange

この関数は、現行のスレッドが特定の状態になったときに呼び出される関数を登録します。

構文

void cciRegisterForThreadStateChange(
int *returnCode,
CciThreadContext *threadContext,
CciDataContext *userContext,
CciRegCallback callback,
CciCallbackType type);

パラメーター

returnCode
関数からの戻りコード (出力)。入力が NULL である場合、これは、エラーがブローカーによってサイレントに処理されるか、無視されることを示します。 入力が NULL でない場合、出力は呼び出しの成功状況を示します。 threadContext パラメーターが無効である場合、*returnCode は CCI_INV_THREAD_CONTEXT に設定され、コールバックは登録されません。
threadContext
これは、コールバック関数および関連データを登録するためのスレッド・コンテキストを指定します。 このパラメーターは、現行のスレッドで cniGetThreadContext() API を使用することにより取得されるものと想定されています。threadContext に NULL が指定されると、スレッド・コンテキストはフレームワークにより判別されます。これは cniGetThreadContext を呼び出すほどに効率的ではありません。
userContext
これは、コールバック関数が呼び出されたときにコールバック関数に渡されるコンテキスト・ポインターを、呼び出し側が提供できるようにするためのものです。 このパラメーターは NULL に設定可能です。
callback
これは、呼び出されるコールバック関数へのポインターです。この関数は、タイプ CciRegCallback でなければなりません。
type
これは、スレッドが終了するときにコールバックを呼び出すか、それともスレッドがアイドル状態の 1 つのときにコールバックを呼び出すかを指定します。 アイドル状態は、以下の値のうちのいずれかになります。
  • CCI_THREAD_STATE_IDLE:

    現行のスレッドの入力ノードは入力ソースからのデータを求めてアクティブにポーリングを行っていますが、使用可能なデータがありません。 入力ノードでデータが使用可能になるまで、メッセージはメッセージ・フローの下流に伝搬されません。

  • CCI_THREAD_STATE_INSTANCE_END

    現行のスレッドの入力ノードはデータのポーリングを停止しており、スレッドは解放されました。 スレッドは、同じ入力ノード、または同じメッセージ・フロー内の別の入力ノードにより、再度ディスパッチされています。 この状態になるのは、メッセージ・フローのためにデプロイされた追加のインスタンスが入力データの殺到を処理するために利用され、この入力データの殺到が現在は途絶えている場合です。入力ノードは、単一スレッド上で入力データのポーリングを継続して、他のスレッドは解放されます。

  • CCI_THREAD_STATE_TERMINATION

    現行のスレッドは終了します。これは、ブローカーがシャットダウンする時、実行グループ・プロセスが制御された方法で終了する時、またはメッセージ・フローが削除される時に発生することがあります。 これは、フロー内のすべてのノードおよびパーサーが削除された後に発生することがあります。

あるいは、type パラメーターを、上記の複数の値に対するビット単位の OR 演算の結果とすることもできます。 この場合、スレッドが個々の type 値に関連する状態になると、指定された関数が呼び出されます。

戻り値

なし。エラーが発生した場合、returnCode パラメーターがエラーの理由を示します。

以下のように構造と関数を宣言します。

typedef struct {
int id;
}MyContext;
static int registered=0;
CciRegCallbackStatus switchThreadStateChange(
CciDataContext *context, CciCallbackType type)
{
char traceText[256];
char* typeStr=0;
MyContext* myContext = (MyContext*)context;
if (type==CCI_THREAD_STATE_IDLE){
typeStr = "idle";
}else if(type==CCI_THREAD_STATE_INSTANCE_END){
typeStr = "instance end";
}else if (type==CCI_THREAD_STATE_TERMINATION){
typeStr = "termination";
}else{
typeStr = "unknown";
}
memset(traceText,0,256);
sprintf(traceText,"switchThreadStateChange: context id = %d, thread state %s",myContext->id,typeStr);
cciServiceTrace(NULL,
NULL,
traceText);
return CCI_THREAD_STATE_REGISTRATION_RETAIN;
}

以下のコードをサンプルの _Switch_evaluate 関数に入れると、サービス・トレースを読んで、メッセージ処理スレッドの状態がいつ変わったかを調べることができるようになります。

/*register for thread state change*/
CciMessageContext* messageContext = cniGetMessageContext(NULL,message);
CciThreadContext* threadContext = cniGetThreadContext(NULL,messageContext);
static MyContext myContext={1};
if(registered==0){
cciRegisterForThreadStateChange(
NULL,
threadContext,
& myContext,
switchThreadStateChange,
CCI_THREAD_STATE_IDLE |
CCI_THREAD_STATE_INSTANCE_END |
CCI_THREAD_STATE_TERMINATION);
registered=1;
}

この例は、メッセージを受け取る最初のスレッドでのみ登録を行います。 メッセージを受け取るすべてのスレッドで登録を行う必要がある場合は、ユーザー定義拡張機能に、どのスレッドで登録を行ったかを記憶させておく必要があります。

userContext パラメーターを使用すると、コールバックが登録されているコードから、実際のコールバック関数へどのようにデータが渡されるかを調べることができます。

コールバックを登録する際、MyContext 構造のインスタンスへのポインターが渡されます。これは、コールバックに戻されるポインターと同じです。 コールバックに戻されるときまで確実にポインターを有効にしておくために、構造のインスタンスが静的インスタンスとして宣言されます。 確実にポインターを有効にしておくための別の手法として、ヒープにストレージを割り振る方法があります。

コールバック関数で、userContext パラメーターを (MyContext*) にキャストできます。元の MyContext 構造は、このアドレスを介して参照可能です。 これにより、コールバックが登録されているコードからコールバック関数にデータを渡すことが可能になります。

特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2006 Last updated: 5 01, 2006
as24630_