IBM Integration Bus, Version 9.0.0.8 Operating Systems: AIX, HP-Itanium, Linux, Solaris, Windows, z/OS

See information about the latest product version

cciRegisterForThreadStateChange

This function registers a function to be called when the current thread enters a particular state.

Syntax

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

Parameters

returnCode
The return code from the function (output). An input value of NULL signifies that errors are silently handled, or are ignored by the broker. If the input value is not NULL, the output value signifies the success status of the call. If the threadContext parameter is not valid, *returnCode is set to CCI_INV_THREAD_CONTEXT, and the callback is not registered.
threadContext
This parameter provides the thread context in which to register the callback function and associated data. It is assumed that this parameter is obtained by calling cniGetThreadContext() on the current thread. If NULL is supplied as threadContext, the thread context is determined by the framework. This method is less efficient than calling cniGetThreadContext.
userContext
This parameter allows the caller to provide a context pointer that is passed to the callback function when it is called. This parameter can be NULL.
callback
This parameter is a pointer to the callback function that is to be called. This function must be of the type CciRegCallback.
type
This parameter specifies whether the callback is to be called at the time when the thread is ending, or when the thread is in one of the idle states. The idle states can be one of the following values:
  • CCI_THREAD_STATE_IDLE:

    The input node for the current thread is actively polling for data from the input source, but no data is available. Messages are not propagated through the message flow until data becomes available for the input node.

  • CCI_THREAD_STATE_INSTANCE_END

    The input node for the current thread has stopped polling for data and the thread has been released. The thread is dispatched again either by the same input node or by another input node in the same message flow. This state is entered when additional instances, which have been deployed for a message flow, have been configured to cope with an influx of input data that has now ceased. The input node continues to poll for input data on a single thread, and the other threads are released.

  • CCI_THREAD_STATE_TERMINATION

    The current thread is ending. This action can happen when the broker is shut down, the integration server process is ending in a controlled manner, or when the message flow is being deleted. This state can occur after all nodes and parsers in the flow are deleted.

Alternatively, the type parameter can be the result of a bit-wise OR operation on two or more of these values. In this case, the specified function is called when the thread enters the relevant state for each individual type value.

Return values

None. If an error occurs, the returnCode parameter indicates the reason for the error.

Example

Declaring the struct and function:

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;

}

Place the following code into the _Switch_evaluate function in the samples to enable you to read service trace, and to see when the message processing thread changes state:

/*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;
  
  }

This example registers only on the first thread that receives a message. If it is necessary to register every thread that receives a message, the user-defined extensions must remember on which threads they have registered.

By using the userContext parameter, you can see how data is passed from the code where the callback is registered to the actual callback function.

When registering the callback, a pointer to an instance of the MyContext struct is passed in. This pointer is the same pointer as is passed back to the callback. To ensure that the pointer is still valid when it is passed back to the callback, an instance of the struct is declared as static. Another technique to ensure that the pointer is valid is to allocate storage on the heap.

In the callback function, the userContext parameter can be cast to a (MyContext*). The original MyContext struct can be referenced through this address. This technique permits the passing of data from the code where the callback is registered to the callback function.


as24630_.htm | Last updated Friday, 21 July 2017