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 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.
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.
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.
Here is a scenario of how a program might use queue-level non-blocking on a full-duplex conversation:
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.
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
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.