Essa é uma função que pode ser registrada como um retorno de chamada e é chamada quando o ocorre o evento registrado. A função é registrada fornecendo um ponteiro de função que corresponde ao seguinte typedef:
type CciRegCallbackStatus (definido em BipCci.h)
Para cada uma dessas cinco funções de utilitários de rastreio, o parâmetro CciObject deve ser NULL.
Declare a seguinte estrutura e função:
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; }
Coloque o código a seguir na função _Switch_evaluate nas amostras, para permitir a leitura do rastreio de serviço e ver quando o encadeamento de processamento de mensagens altera o estado:
/*registrar para alteração no estado de encadeamento*/ 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; }
Esse exemplo é registrado apenas no primeiro encadeamento que recebe uma mensagem. Se for necessário registrar cada encadeamento que recebe uma mensagem, as extensões definidas pelo usuário devem lembrar em quais encadeamentos elas foram registradas.
Utilizando o parâmetro userContext, você pode ver como os dados são transmitidos do código, no qual o retorno de chamada é registrado para a função de retorno de chamada real.
Ao registrar o retorno de chamada, é transmitido um ponteiro para uma instância da estrutura MyContext. Esse é o mesmo ponteiro, pois é transmitido novamente para o retorno de chamada. Para assegurar que o ponteiro ainda é válido quando transmitido novamente para o retorno de chamada, uma instância da estrutura é declarada como estática. Outra técnica é assegurar que o ponteiro é válido para alocar o armazenamento no heap.
Na função de retorno de chamada, o parâmetro userContext pode ser convertido em um (MyContext*). A estrutura MyContext original pode ser referenciada através desse endereço. Isso permite a transmissão de dados do código no qual o retorno de chamada é registrado para a função de retorno de chamada.