CPI-C Reference


Non-Blocking Operations

CPI Communications supports two processing modes for its calls:

Note: This section describes non-blocking operations for a single-threaded program, but similar considerations apply to a program issuing CPI Communications calls on multiple threads. Specifically, only the thread that issues a call is blocked if the call is processed in blocking mode and cannot complete immediately. When the program uses non-blocking support, control is returned to the calling thread if the call operation cannot complete immediately. That thread may then perform other processing, including issuing calls on the same conversation.

When the non-blocking processing mode applies to a call and the call operation cannot complete immediately, CPI Communications returns control to the program with a return code of CM_OPERATION_INCOMPLETE. The call operation remains in progress as an outstanding operation, and the program is allowed to perform other processing.

The following calls can return the CM_OPERATION_INCOMPLETE return code:

Table 7. Calls Returning CM_OPERATION_INCOMPLETE
Accept_Incoming
Allocate
Confirm
Confirmed
Deallocate
Deferred_Deallocate
Flush
Include_Partner_In_Transaction
Prepare
Prepare_To_Receive
Receive
Receive_Expedited_Data
Receive_Mapped_Data
Request_To_Send
Send_Data
Send_Error
Send_Expedited_Data
Send_Mapped_Data

CPI Communications provides two levels of support for programs using the non-blocking processing mode: conversation level and queue level. These are discussed in the sections below. Until a program chooses a non-blocking level for a conversation, all calls on the conversation are processed in blocking mode.

Note: A program may choose to use conversation-level non-blocking or queue-level non-blocking, but not both, on a given conversation. Once set, the level of non-blocking used on a conversation cannot be changed. Additionally, the level of non-blocking used depends on the send_receive_mode characteristic. The program can choose to use either level of non-blocking support on a half-duplex conversation. However, the program can use only queue-level non-blocking on a full-duplex conversation.

Conversation-Level Non-Blocking

Conversation-level non-blocking allows only one outstanding operation on a conversation at a time. The program chooses conversation-level non-blocking by issuing the Set_Processing_Mode (CMSPM) call to set the processing_mode conversation characteristic. The processing_mode characteristic indicates whether subsequent calls on the conversation are to be processed in blocking or non-blocking mode.

If processing_mode is set to CM_NON_BLOCKING and a call receives the CM_OPERATION_INCOMPLETE return code, the call operation becomes an outstanding operation on the conversation. The program must issue the Wait_For_Conversation (CMWAIT) call to determine when the outstanding operation is completed and to retrieve the return code for that operation. CPI Communications keeps track of all conversations using conversation-level non-blocking and having an outstanding operation, and responds to a subsequent Wait_For_Conversation call with the conversation identifier of one of those conversations when the operation on it completes.

With conversation-level non-blocking, only one call operation is allowed to be in progress on the conversation at a time. Any call (except Cancel_Conversation) issued on the conversation while the previous call operation is still in progress gets the CM_OPERATION_NOT_ACCEPTED return code.

A conversation does not change conversation state when a call on that conversation gets the CM_OPERATION_INCOMPLETE return code. Instead, the state transition occurs when a subsequent Wait_For_Conversation call completes and indicates that the conversation has a completed operation. The conversation enters the state called for by a combination of the operation that completed, the return code for that operation (the conversation_return_code value returned on the Wait_For_Conversation call), and the other factors that determine state transitions.

Queue-Level Non-Blocking

In contrast to conversation-level non-blocking, queue-level non-blocking allows more than one outstanding operation per conversation. CPI Communications allows programs using queue-level non-blocking to have one outstanding operation per queue simultaneously.

With queue-level non-blocking, the processing mode is set on a queue basis. The program chooses queue-level non-blocking by issuing the Set_Queue_Processing_Mode (CMSQPM) or Set_Queue_Callback_Function (CMSQCF) call to set the queue processing mode for a specified queue. Until the program sets the processing mode for a queue, all calls associated with that queue are processed in blocking mode. Calls not associated with any queue are processed in blocking mode and are always completed before control is returned to the program.

Working with Wait Facility

When using the Set_Queue_Processing_Mode call, the program manages multiple outstanding operations with outstanding-operation identifiers, or OOIDs. CPI Communications creates and maintains a unique OOID for each queue. Additionally, a program may choose to associate a user field with an outstanding operation. The user field is provided as an aid to programming, and might be used to contain, for example, the address of a data structure with return parameters for an outstanding operation.

When a call receives the CM_OPERATION_INCOMPLETE return code, the call operation becomes an outstanding operation on the conversation queue with which the call is associated. The program must issue the Wait_For_Completion call to wait for the operation to complete and to obtain the corresponding OOID and user field.

Wait Facility Scenario

Here is a scenario of how a program might use queue-level non-blocking on a full-duplex conversation:

  1. The program uses the Set_Queue_Processing_Mode call to set the processing mode for the Send queue to non-blocking. It also supplies a user field that contains the address of a parameter list for the Send_Data call and receives back an OOID from CPI Communications that is unique to the Send queue.

  2. The program next uses the Set_Queue_Processing_Mode call to set the processing mode for the Receive queue to non-blocking. This time it supplies a user field that contains the address of a parameter list for the Receive call. It receives back an OOID from CPI Communications that is unique to the Receive queue.

  3. The program issues a Send_Data call, which returns CM_OPERATION_INCOMPLETE, followed by a Receive call, which also returns CM_OPERATION_INCOMPLETE. If the program attempted to issue another call associated with either queue, it would receive a CM_OPERATION_NOT_ACCEPTED return code because there can be only one outstanding operation at a time per queue. Note that when a call on a conversation receives a CM_OPERATION_INCOMPLETE return code, the conversation does not change state.

  4. The program can now issue a Wait_For_Completion call to wait for both outstanding operations at the same time. It does this by specifying a list of OOIDs for the outstanding operations it wants to wait for. When the Wait_For_Completion call returns, it indicates which operations have completed (if any), along with a list of user fields. The state transition triggered by the completed operation occurs when the Wait_For_Completion call completes.

  5. The program uses the parameter-list address in the user field to determine the results of a given completed operation.

Using Callback Function

An alternative use of queue-level non-blocking is to establish a callback function and a user field for the conversation queue using the Set_Queue_Callback_Function (CMSQCF) call. When an outstanding operation completes, the program is interrupted and the callback function is called (passing the user field and call ID for the completed operation as input data). See Set_Queue_Callback_Function (CMSQCF) for details. When the callback function returns, the program continues from where it was interrupted.

Canceling Outstanding Operations

A program may use the Cancel_Conversation (CMCANC) call to end a conversation. The call terminates all the call operations in progress on the conversation. The terminated call operation returns a code of CM_CONVERSATION_CANCELLED

Non-Blocking Calls and Context Management

In general, the program's current context is set by node services to the newly created context when an Accept_Conversation or Accept_Incoming call completes successfully with a return code of CM_OK. However, if Accept_Incoming is issued as a non-blocking call and returns with a CM_OPERATION_INCOMPLETE return code, the program's current context will not be changed. A new context is not created until the Accept_Incoming call operation subsequently completes successfully as a result of the Wait_For_Conversation or Wait_For_Completion call. The program can then use the Extract_Conversation_Context call to determine the context to which the conversation was assigned. Because Wait_For_Conversation and Wait_For_Completion do not cause a change of context, the program is responsible for issuing the appropriate node services call to establish the correct current context.


[ Top of Page | Previous Page | Next Page | Table of Contents ]