Diese Funktion registriert eine Funktion, die aufzurufen ist, wenn der aktuelle Thread in einen bestimmten Zustand geht.
void cciRegisterForThreadStateChange( int *returnCode, CciThreadContext *threadContext, CciDataContext *userContext, CciRegCallback callback, CciCallbackType type);
Der Empfangsknoten für den aktuellen Thread fragt aktiv nach Daten aus der Eingabequelle, aber es sind keine Daten verfügbar. Es werden keine Nachrichten den Nachrichtenfluss entlang propagiert, bis Daten für den Empfangsknoten verfügbar werden.
Der Empfangsknoten für den aktuellen Thread hat aufgehört, nach Daten zu fragen, und der Thread ist wieder freigegeben worden. Der Thread wird entweder vom selben Empfangsknoten oder einem beliebigen anderen Empfangsknoten im selben Nachrichtenfluss erneut zugeteilt. In diesen Status wird gewechselt, wenn zusätzliche Instanzen, die für einen Nachrichtenfluss implementiert worden waren, verwendet wurden, um mit einem Zustrom von Daten zurecht zu kommen, der nun aufgehört hat. Der Empfangsknoten fragt auf einem einzelnen Thread weiter nach Eingabe, und die übrigen Threads werden freigegeben.
Der aktuelle Thread endet. Dies kann geschehen, wenn der Broker beendet wird, der Ausführungsgruppenprozess kontrolliert endet, oder der Nachrichtenfluss gelöscht wird. Dies kann vorkommen, nachdem alle Knoten und Parser im Fluss gelöscht worden sind.
Alternativ kann es sich beim Parametertype um das Ergebnis einer bitweisen ODER-Operation auf zwei oder mehr von diesen Werten handeln. In diesem Fall wird die angegebene Funktion aufgerufen, wenn der Thread für jeden einzelnen type-Wert in den betreffenden Status geht.
Deklarieren von Struct und Funktion:
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; }
Fügen Sie den folgenden Code in die Funktion _Switch_evaluate aus den mitgelieferten Muster-Codes ein, um den Service-Trace lesen und sehen zu können, wann der Nachrichtenverarbeitungs-Thread seinen Status wechselt:
/*für Thread-Statuswechsel registrieren*/ 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; }
In diesem Beispiel wird nur der erste Thread registriert, der eine Nachricht empfängt. Wenn es nötig ist, jeden Thread zu registrieren, der eine Nachricht empfängt, dann müssen die benutzerdefinierten Erweiterungen sich merken, auf welchen Threads sie sich registriert haben.
Mit Hilfe des Parameters userContext können Sie nachvollziehen, wie Daten von dem Code aus, in dem der Callback registriert wird, an die eigentliche Callback-Funktion übergeben werden.
Beim Registrieren des Callbacks wird ein Zeiger auf eine Instanz des Structs MyContext übergeben. Dies ist derselbe Zeiger, der an den Callback zurück übergeben wird. Um sicher zu stellen, dass der Zeiger noch gültig ist, wenn er an den Callback zurück übergeben wird, wird ein Instanz des Structs als statisch deklariert. Ein anderes Vorgehen, um sicher zu stellen, dass der Zeiger gültig ist, ist, Speicherplatz auf dem Heap zuzuweisen.
In der Callback-Funktion kann der Parameter userContext in den Typ (MyContext*) konvertiert werden. Das ursprüngliche Struct MyContext kann durch diese Adresse referenziert werden. So ist es möglich, Daten von dem Code aus, wo der der Callback registriert wird, an die Callback-Funktion zu übergeben.