TipcConnMsgSearch


Name

TipcConnMsgSearch — search the message queue of a connection for a specific message

Synopsis

T_IPC_MSG TipcConnMsgSearch(conn, timeout, func, arg) 
T_IPC_CONN conn; 
T_REAL8 timeout; 
T_IPC_CONN_MSG_SEARCH_FUNC func; 
T_PTR arg; 

Arguments

conn — connection to search

timeout — maximum number of seconds to wait for desired message to arrive

func — function to call once for each message

arg — user-defined argument to pass to func

Return Values

A message if successful, NULL otherwise.

Diagnostics

If TipcConnMsgSearch fails, it returns NULL and sets the global SmartSockets error number to one of:

Description

TipcConnMsgSearch searches the message queue of a connection for a specific message. A connection has a priority queue of incoming messages. TipcConnMsgSearch traverses the messages in the queue and calls func once for each message. When func returns TRUE, TipcConnMsgSearch removes the message from the queue, calls the connection’s queue callbacks, and returns the message. If TipcConnMsgSearch reaches the end of the queue, it calls TipcConnRead with the time remaining from timeout, and searches the queue again. TipcConnMsgSearch continues reading and searching until func returns TRUE, TipcConnRead returns FALSE, or the timeout is reached. As a convenience, TipcConnMsgSearch sets the current field of the returned message to field number 0 (the first field) with TipcMsgSetCurrent.

TipcConnMsgSearch is useful for processing messages out of priority order, such as when waiting for the result from a remote procedure call or when checking for a message of a specific type. To get the first message from the message queue, use TipcConnMsgNext instead. Once a message is acquired by calling TipcConnMsgSearch, it is normally processed (either with TipcConnMsgProcess or by accessing it directly without any callbacks) and then destroyed by calling TipcMsgDestroy. Use 0.0 for timeout to search for a message without blocking. Use T_TIMEOUT_FOREVER for timeout to wait until a message arrives. To search for a message with a specific type, use the convenience function TipcConnMsgSearchType.

Caution

The message returned by TipcConnMsgSearch should be destroyed when it is no longer needed by calling TipcMsgDestroy, unless the message is passed to another function which takes responsibility for destroying the message (such as TipcConnMsgInsert).

The T_ENTRY declaration specifier is required in the definition of all callback functions as well as their prototypes.

See Also

TipcConnMsgProcess, TipcConnMsgSearchType, TipcConnRead

Examples

Remote procedure calls (RPCs) can be easily implemented between two ends of a connection by the caller end sending one message as the call and other end sending one message back as the result. This example calculates the tangent of a number with such an RPC. It sends a call message and waits for up to 10 seconds for a result message to be sent back from the other end of the connection. User code would normally use TipcConnMsgSendRpc (or even just TipcConnMsgSearchType) to implement this, but this example uses TipcConnMsgSearch to show the functionality in more detail. Shown first is the caller fragment:

#define USER_MT_TANGENT_CALL 100 
#define USER_MT_TANGENT_RESULT 101 
 
/* search function */ 
static T_BOOL T_ENTRY search_for_result(conn, msg, arg) 
T_IPC_CONN conn; 
T_IPC_MSG msg; 
T_PTR arg; /* not used */ 
{ 
  T_BOOL status; 
  T_IPC_MT mt; 
  T_INT4 num; 
 
  if (!TipcMsgGetType(msg, &mt)) { 
    return;  /* error */ 
  }  
  if (!TipcMtGetNum(mt, &num)) { 
    return;  /* error */ 
  }  
 
  /* return TRUE if message type matches what we want */ 
  return num == USER_MT_TANGENT_RESULT; 
} /* search_for_result */ 
/* calculate tangent via RPC */ 
T_REAL8 tangent_rpc(num) 
T_REAL8 num; 
{ 
  T_IPC_MT mt; 
  T_IPC_MSG msg; 
  T_REAL8 result; 
 
  mt = TipcMtLookupByNum(USER_MT_TANGENT_CALL); 
  if (mt == NULL) { 
    return;  /* error */ 
  } 
 
  if (!TipcConnMsgWrite(conn, mt, 
                        T_IPC_FT_REAL8, num, 
                        NULL)) { 
    return;  /* error */ 
  } 
 
  /* assume auto flush size is not T_IPC_NO_AUTO_FLUSH, thus */ 
  /* no flush needed */ 
 
  /* search for result message */ 
  msg = TipcConnMsgSearch(conn, 10.0, search_for_result, NULL); 
  if (msg == NULL) { 
    return;  /* error */ 
  }  
 
  /* process result without using TipcConnMsgProcess */ 
 
  if (!TipcMsgNextReal8(msg, &result)) { 
    return;  /* error */ 
  }  
  if (!TipcMsgDestroy(msg)) { 
    return;  /* error */ 
  }  
  return result; 
} /* tangent_rpc */ 
 

This is the called fragment:

/* callback to process RPC "call" message */ 
static T_ENTRY void process_call(conn, data, arg) 
T_IPC_CONN conn; 
T_IPC_CONN_PROCESS_CB_DATA data; 
T_CB_ARG arg; 
{ 
  T_REAL8 num; 
  T_IPC_MT mt; 
 
  /* have to start at first field */ 
  if (!TipcMsgSetCurrent(data->msg, 0)) { 
    return;  /* error */ 
  }  
 
  /* access the RPC call information */ 
  if (!TipcMsgNextReal8(data->msg, &num)) { 
    return;  /* error */ 
  }  
 
  /* send a result message back to the caller */ 
  mt = TipcMtLookupByNum(USER_MT_TANGENT_RESULT); 
  if (mt == NULL) { 
    return;  /* error */ 
  }  
 
  if (!TipcConnMsgWrite(conn, mt, 
                        T_IPC_FT_REAL8, tan(num), 
                        NULL)) { 
  return;  /* error */ 
  } 
 
  if (!TipcConnFlush(conn)) { 
    return;  /* error */ 
  }  
} /* process_call */ 
 
/* =========================================================== */ 
/*...code from calling function is below */ 
 
/* fragment that uses process_call */ 
T_IPC_MT mt; 
 
mt = TipcMtLookupByNum(USER_MT_TANGENT_CALL); 
if (mt == NULL) { 
  return;  /* error */ 
} 
 
if (TipcConnProcessCbCreate(conn, mt, process_call, NULL) == NULL) 
{ 
  return;  /* error */ 
}  
TipcConnMainLoop(conn, T_TIMEOUT_FOREVER); /* process call messages */ 

TIBCO SmartSockets™ Application Programming Interface
Software Release 6.8, July 2006
Copyright © TIBCO Software Inc. All rights reserved
www.tibco.com