cciRegisterForThreadStateChange

此函数注册一个函数,当前线程进入某个特殊状态时会调用此函数。

语法

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

参数

returnCode
来自函数(输出)的返回码。如果输入为 NULL,则表示静默地处理这些错误或者由代理忽略它们。如果输入不是 NULL,则输出表示调用的成功状态。 如果 threadContext 参数无效,则 *returnCode 设置成 CCI_INV_THREAD_CONTEXT,并且不注册回调。
threadContext
它提供线程上下文,在该上下文中注册回调函数和相关联的数据。假设通过在当前线程上使用 cniGetThreadContext() 获得此参数。如果 threadContext 为 NULL,则线程上下文由框架确定。这比调用 cniGetThreadContext 效率差些。
userContext
这允许调用者提供上下文指针,调用该指针时该指针会传递给回调函数。该参数可以为 NULL。
callback
这是要被调用的回调函数的指针。该函数必须是 CciRegCallback 类型。
type
它指定当线程结束时或线程处于空闲状态时是否要调用回调。空闲状态可以是以下值之一:
  • CCI_THREAD_STATE_IDLE:

    当前线程的输入节点主动轮询输入源的数据,但是没有数据可用。在数据可用于输入节点之前,消息不沿着消息流向下传播。

  • CCI_THREAD_STATE_INSTANCE_END

    当前线程的输入节点已停止轮询数据,并且该线程已被释放。通过同一个消息流中的同一个输入节点或任何其他输入节点,再次分配该线程。当利用了为消息流部署的附加实例来应付现已停止的输入数据的流入时,进入此状态。输入节点继续轮询单线程处理方式的输入数据和其他已释放的线程。

  • CCI_THREAD_STATE_TERMINATION

    正在结束当前线程。当代理关闭时、控制方式中的执行组访问结束或删除消息流时,会发生此情况。删除了消息流中的所有节点和解析器后会发生此情况。

或者,type 参数可以是两个或多个这些值的 bit wise OR 操作的结果。 在这种情况下,当线程进入每个单独的 type 值的相关状态时,调用指定的函数:

返回值

无。 如果发生错误,则 returnCode 参数表明错误原因。

示例

声明 struct 和函数:

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 struct 的实例的指针。该指针与传回回调的指针相同。要确保该指针在传递到回调时仍然有效,将 struct 的实例声明为静态。另一个确保指针有效的技术是在堆上分配存储。

在回调函数中,可以将 userContext 参数类型强制转换成 (MyContext*)。可以通过此地址引用原始的 MyContext struct。这允许数据从注册回调的代码传递到该回调函数。

声明 | 商标 | 下载 | 书库 | 支持 | 反馈
Copyright IBM Corporation 1999, 2006 最后一次更新时间:2006/08/14
as24630_