Questa è una funzione che può essere registrata come callback e viene richiamata quando si verifica l'evento registrato. La funzione viene registrata fornendo un puntatore di funzione che corrisponde al seguente typedef:
type CciRegCallbackStatus (definito in BipCci.h)
Per ciascuna di queste cinque funzioni di utilità di traccia, il parametro CciObject deve essere NULL.
Dichiarare il seguente struct e funzione:
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; }
Inserire il seguente codice nella funzione _Switch_evaluate negli esempi per abilitare la lettura della traccia del servizio e per vedere quando il thread di elaborazione del messaggio cambia stato:
/*registro del cambiamento di stato del thread*/ 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 questo esempio viene registrato solo il primo thread che riceve un messaggio. Se è necessario registrare tutti i thread che ricevono un messaggio, è necessario che le estensioni definite dall'utente ricordino i thread sui quali sono registrate.
Mediante l'uso del parametro userContext è possibile vedere come i dati vengono passati dal codice dove è registrata la funzione callback alla funzione callback attuale.
Quando si registra la callback, viene passato un puntatore ad un'istanza dello struct MyContext. Questo è lo stesso puntatore così come ripassato alla funzione callback. Per accertarsi che il puntatore sia ancora valido quando viene ripassato alla callback, un'istanza dello struct viene dichiarata come statica. Un altro modo per accertarsi che il puntatore sia valido è quello di assegnare memoria sull'heap.
Nella funzione callback, il parametro userContext può essere impostato su un (MyContext*). E' possibile fare riferimento allo struct MyContext di origine mediante questo indirizzo. Ciò consente il passaggio dei dati dal codice in cui la callback è registrata nella funzione callback.