MQCB - Manage callback
The MQCB call registers a callback for the specified object handle and controls activation and changes to the callback.
A callback is a piece of code (specified as either the name of a function that can be dynamically linked or as function pointer) that is called by IBM MQ when certain events occur.
To use MQCB and MQCTL on a client we must be connected to a server where the negotiated SHARECNV parameter of the channel has agreed a non-zero value.
The types of callback that can be defined are:
- Message consumer
- A message consumer callback function is called when a message, meeting the selection criteria specified, is available on an object handle.
Only one callback function can be registered against each object handle. If a single queue is to be read with multiple selection criteria then the queue must be opened multiple times and a consumer function registered on each handle.
- Event handler
- The event handler is called for conditions that affect the whole callback environment.
The function is called when an event condition occurs, for example, a queue manager or connection stopping or quiescing.
The function is not called for conditions that are specific to a single message consumer, for example MQRC_GET_INHIBITED; it is called however if a callback function does not end normally.
Syntax
MQCB (Hconn, Operation, CallbackDesc, Hobj, MsgDesc, GetMsgOpts, CompCode, Reason)
Parameters
- Hconn
- Type: MQHCONN - input
This handle represents the connection to the queue manager. The value of Hconn was returned by a previous MQCONN or MQCONNX call.
On z/OS for CICS applications we can specify the following special value for MQHC_DEF_HCONN to use the connection handle associated with this execution unit.
- Operation
- Type: MQLONG - input
The operation being processed on the callback defined for the specified object handle. We must specify one of the following options. To specify more than one option, either add the values together (do not add the same constant more than once), or combine the values using the bitwise OR operation (if the programming language supports bit operations).
- MQOP_REGISTER
- Define the callback function for the specified object handle. This operation defines the function to be called and the selection criteria to be used.
If a callback function is already defined for the object handle the definition is replaced. If an error is detected while replacing the callback, the function is deregistered.
If a callback is registered in the same callback function in which it was previously deregistered, this is treated as a replace operation; any initial or final calls are not invoked.
We can use MQOP_REGISTER with MQOP_SUSPEND or MQOP_RESUME.
- MQOP_DEREGISTER
- Stop the consuming of messages for the object handle and removes the handle from those eligible for a callback.
A callback is automatically deregistered if the associated handle is closed.
If MQOP_DEREGISTER is called from within a consumer, and the callback has a stop call defined, it is invoked upon return from the consumer.
If this operation is issued against an Hobj with no registered consumer, the call returns with MQRC_CALLBACK_NOT_REGISTERED.
- MQOP_SUSPEND
- Suspends the consuming of messages for the object handle.
If this operation is applied to an event handler, the event handler does not get events while suspended, and any events missed while in the suspended state are not provided to the operation when it is resumed.
While suspended, the consumer function continues to get the control type callbacks.
- MQOP_RESUME
- Resume the consuming of messages for the object handle.
If this operation is applied to an event handler, the event handler does not get events while suspended, and any events missed while in the suspended state are not provided to the operation when it is resumed.
- CallbackDesc
- Type: MQCBD - input
This is a structure that identifies the callback function that is being registered by the application and the options used when registering it.
See MQCBD for details of the structure.
Callback descriptor is required only for the MQOP_REGISTER option; if the descriptor is not required, the parameter address passed can be null.
- Hobj
- Type: MQHOBJ - input
This handle represents the access that has been established to the object from which a message is to be consumed. This is a handle that has been returned from a previous MQOPEN or MQSUB call (in the Hobj parameter).
Hobj is not required when defining an event handler routine (MQCBT_EVENT_HANDLER) and should be specified as MQHO_NONE.
If Hobj has been returned from an MQOPEN call, the queue must have been opened with one or more of the following options:- MQOO_INPUT_SHARED
- MQOO_INPUT_EXCLUSIVE
- MQOO_INPUT_AS_Q_DEF
- MQOO_BROWSE
- MsgDesc
- Type: MQMD - input
This structure describes the attributes of the message required, and the attributes of the message retrieved.
The MsgDesc parameter defines the attributes of the messages required by the consumer, and the version of the MQMD to be passed to the message consumer.
The MsgId, CorrelId, GroupId, MsgSeqNumber, and Offset in the MQMD are used for message selection, depending on the options specified in the GetMsgOpts parameter.
The Encoding and CodedCharSetId are used for message conversion if we specify the MQGMO_CONVERT option.
See MQMD for details.
MsgDesc is used for MQOP_REGISTER and if you require values other than the default for any fields. MsgDesc is not used for an event handler.
If the descriptor is not required the parameter address passed can be null.
Note, that if multiple consumers are registered against the same queue with overlapping selectors, the chosen consumer for each message is undefined.
- GetMsgOpts
- Type: MQGMO - input
The GetMsgOpts parameter controls how the message consumer gets messages. All options of this parameter
have meanings as described in MQGMO - Get-message options, when used on an MQGET call, except:
- MQGMO_SET_SIGNAL
- This option is not permitted.
- MQGMO_BROWSE_FIRST, MQGMO_BROWSE_NEXT, MQGMO_MARK_*
- The order of messages delivered to a browsing consumer is dictated by the combinations of these
options. Significant combinations are:
- MQGMO_BROWSE_FIRST
- The first message on the queue is delivered repeatedly to the consumer. This is useful when the consumer destructively consumes the message in the callback. Use this option with care.
- MQGMO_BROWSE_NEXT
- The consumer is given each message on the queue, from the current cursor position until the end of the queue is reached.
- MQGMO_BROWSE_FIRST + MQGMO_BROWSE_NEXT
- The cursor is reset to the start of the queue. The consumer is then given each message until the cursor reaches the end of the queue.
- MQGMO_BROWSE_FIRST + MQGMO_MARK_*
- Starting at the beginning of the queue, the consumer is given the first nonmarked message on the queue, which is then marked for this consumer. This combination ensures that the consumer can receive new messages added behind the current cursor point.
- MQGMO_BROWSE_NEXT + MQGMO_MARK_*
- Starting at the cursor position, the consumer is given the next nonmarked message on the queue, which is then marked for this consumer. Use this combination with care because messages can be added to the queue behind the current cursor position.
- MQGMO_BROWSE_FIRST + MQGMO_BROWSE_NEXT + MQGMO_MARK_*
- This combination is not permitted. If used the call returns MQRC_OPTIONS_ERROR.
- MQGMO_NO_WAIT, MQGMO_WAIT, and WaitInterval
- These options control how the consumer is invoked.
- MQGMO_NO_WAIT
- The consumer is never called with MQRC_NO_MSG_AVAILABLE. The consumer is only called for messages and events.
- MQGMO_WAIT with a zero WaitInterval
- The MQRC_NO_MSG_AVAILABLE code is passed to the consumer when there are no messages available and either the consumer has been started or the consumer has been delivered at least one message since the last "no messages" reason code.
- MQGMO_WAIT and a positive WaitInterval
- The consumer is called after the specified wait interval with reason code MQRC_NO_MSG_AVAILABLE. This call is made regardless of whether any messages have been delivered to the consumer. This allows the user to perform heartbeat or batch type processing.
- MQGMO_WAIT and WaitInterval of MQWI_UNLIMITED
- This specifies an infinite wait before returning MQRC_NO_MSG_AVAILABLE. The consumer is never called with MQRC_NO_MSG_AVAILABLE.
GetMsgOpts is used only for MQOP_REGISTER and if you require values other than the default for any fields. GetMsgOpts is not used for an event handler.
If the GetMsgOpts are not required, the parameter address passed can be null. Using this parameter is the same as specifying MQGMO_DEFAULT together with MQGMO_FAIL_IF_QUIESCING.
If a message properties handle is provided in the MQGMO structure, a copy is provided in the MQGMO structure that is passed into the consumer callback. On return from the MQCB call, the application can delete the message properties handle.
- CompCode
- Type: MQLONG - output
The completion code; it is one of the following:
- MQCC_OK
- Successful completion.
- MQCC_WARNING
- Warning (partial completion).
- MQCC_FAILED
- Call failed.
- Reason
- Type: MQLONG - output
The reason codes in the following list are the ones that the queue manager can return for the Reason parameter.
If CompCode is MQCC_OK:- MQRC_NONE
- (0, X'000') No reason to report.
If CompCode is MQCC_FAILED:
- MQRC_ADAPTER_NOT_AVAILABLE
- (2204, X'89C') Adapter not available.
- MQRC_ADAPTER_CONV_LOAD_ERROR
- (2133, X'855') Unable to load data conversion services modules.
- MQRC_ADAPTER_SERV_LOAD_ERROR
- (2130, X'852') Unable to load adapter service module.
- MQRC_API_EXIT_ERROR
- (2374, X'946') API exit failed.
- MQRC_API_EXIT_LOAD_ERROR
- (2183, X'887') Unable to load API exit.
- MQRC_ASID_MISMATCH
- (2157, X'86D') Primary and home ASIDs differ.
- MQRC_BUFFER_LENGTH_ERROR
- (2005, X'7D5') Buffer length parameter not valid.
- MQRC_CALL_IN_PROGRESS
- (2219, X'8AB') MQI call entered before previous call complete.
- MQRC_CALLBACK_LINK_ERROR
- (2487, X'9B7') Incorrect callback type field.
- MQRC_CALLBACK_NOT_REGISTERED
- (2448, X'990') Unable to unregister, suspend, or resume because there is no registered callback.
- MQRC_CALLBACK_ROUTINE_ERROR
- (2486, X'9B6') Either CallbackFunction or CallbackName must be specified but not both.
- MQRC_CALLBACK_TYPE_ERROR
- (2483, X'9B3') Incorrect callback type field.
- MQRC_CBD_OPTIONS_ERROR
- (2484, X'9B4') Incorrect MQCBD options field.
- MQRC_CICS_WAIT_FAILED
- (2140, X'85C') Wait request rejected by CICS.
- MQRC_CONNECTION_BROKEN
- (2009, X'7D9') Connection to queue manager lost.
- MQRC_CONNECTION_NOT_AUTHORIZED
- (2217, X'8A9') Not authorized for connection.
- MQRC_CONNECTION_QUIESCING
- (2202, X'89A') Connection quiescing.
- MQRC_CONNECTION_STOPPING
- (2203, X'89B') Connection shutting down.
- MQRC_CORREL_ID_ERROR
- (2207, X'89F') Correlation-identifier error.
- MQRC_DATA_LENGTH_ERROR
- (2010, X'7DA') Data length parameter not valid.
- MQRC_FUNCTION_NOT_SUPPORTED
- (2298, X'8FA') The function requested is not available in the current environment.
- MQRC_GET_INHIBITED
- (2016, X'7E0') Gets inhibited for the queue.
- MQRC_GLOBAL_UOW_CONFLICT
- (2351, X'92F') Global units of work conflict.
- MQRC_GMO_ERROR
- (2186, X'88A') Get-message options structure not valid.
- MQRC_HANDLE_IN_USE_FOR_UOW
- (2353, X'931') Handle in use for global unit of work.
- MQRC_HCONN_ERROR
- (2018, X'7E2') Connection handle not valid.
- MQRC_HOBJ_ERROR
- (2019, X'7E3') Object handle not valid.
- MQRC_INCONSISTENT_BROWSE
- (2259, X'8D3') Inconsistent browse specification.
- MQRC_INCONSISTENT_UOW
- (2245, X'8C5') Inconsistent unit-of-work specification.
- MQRC_INVALID_MSG_UNDER_CURSOR
- (2246, X'8C6') Message under cursor not valid for retrieval.
- MQRC_LOCAL_UOW_CONFLICT
- (2352, X'930') Global unit of work conflicts with local unit of work.
- MQRC_MATCH_OPTIONS_ERROR
- (2247, X'8C7') Match options not valid.
- MQRC_MAX_MSG_LENGTH_ERROR
- (2485, X'9B4') Incorrect MaxMsgLength field.
- MQRC_MD_ERROR
- (2026, X'7EA') Message descriptor not valid.
- MQRC_MODULE_ENTRY_NOT_FOUND
- (2497, X'9C1') The specified function entry point could not be found in the module.
- MQRC_MODULE_INVALID
- (2496, X'9C0') Module found, however it is of the wrong type; not 32 bit, 64 bit, or a valid dynamic link library.
- MQRC_MODULE_NOT_FOUND
- (2495, X'9BF') Module not found in the search path or not authorized to load.
- MQRC_MSG_SEQ_NUMBER_ERROR
- (2250, X'8CA') Message sequence number not valid.
- MQRC_MSG_TOKEN_ERROR
- (2331, X'91B') Use of message token not valid.
- MQRC_NO_MSG_AVAILABLE
- (2033, X'7F1') No message available.
- MQRC_NO_MSG_UNDER_CURSOR
- (2034, X'7F2') Browse cursor not positioned on message.
- MQRC_NOT_OPEN_FOR_BROWSE
- (2036, X'7F4') Queue not open for browse.
- MQRC_NOT_OPEN_FOR_INPUT
- (2037, X'7F5') Queue not open for input.
- MQRC_OBJECT_CHANGED
- (2041, X'7F9') Object definition changed since opened.
- MQRC_OBJECT_DAMAGED
- (2101, X'835') Object damaged.
- MQRC_OPERATION_ERROR
- (2206, X'89E') Incorrect operation code on API Call.
- MQRC_OPTIONS_ERROR
- (2046, X'7FE') Options not valid or not consistent.
- MQRC_PAGESET_ERROR
- (2193, X'891') Error accessing page-set data set.
- MQRC_Q_DELETED
- (2052, X'804') Queue has been deleted.
- MQRC_Q_INDEX_TYPE_ERROR
- (2394, X'95A') Queue has wrong index type.
- MQRC_Q_MGR_NAME_ERROR
- (2058, X'80A') Queue manager name not valid or not known.
- MQRC_Q_MGR_NOT_AVAILABLE
- (2059, X'80B') Queue manager not available for connection.
- MQRC_Q_MGR_QUIESCING
- (2161, X'871') Queue manager quiescing.
- MQRC_Q_MGR_STOPPING
- (2162, X'872') Queue manager shutting down.
- MQRC_RESOURCE_PROBLEM
- (2102, X'836') Insufficient system resources available.
- MQRC_SIGNAL_OUTSTANDING
- (2069, X'815') Signal outstanding for this handle.
- MQRC_STORAGE_NOT_AVAILABLE
- (2071, X'817') Insufficient storage available.
- MQRC_SUPPRESSED_BY_EXIT
- (2109, X'83D') Call suppressed by exit program.
- MQRC_SYNCPOINT_LIMIT_REACHED
- (2024, X'7E8') No more messages can be handled within current unit of work.
- MQRC_SYNCPOINT_NOT_AVAILABLE
- (2072, X'818') Sync point support not available.
- MQRC_UNEXPECTED_ERROR
- (2195, X'893') Unexpected error occurred.
- MQRC_UOW_ENLISTMENT_ERROR
- (2354, X'932') Enlistment in global unit of work failed.
- MQRC_UOW_MIX_NOT_SUPPORTED
- (2355, X'933') Mixture of unit-of-work calls not supported.
- MQRC_UOW_NOT_AVAILABLE
- (2255, X'8CF') Unit of work not available for the queue manager to use.
- MQRC_WAIT_INTERVAL_ERROR
- (2090, X'82A') Wait interval in MQGMO not valid.
- MQRC_WRONG_GMO_VERSION
- (2256, X'8D0') Wrong version of MQGMO supplied.
- MQRC_WRONG_MD_VERSION
- (2257, X'8D1') Wrong version of MQMD supplied.
For detailed information about these codes, see Reason codes.
Usage notes
- MQCB is used to define the action to be invoked for each message, matching the specified criteria, available on the queue. When the action is processed, either the message is removed from the queue and passed to the defined message consumer, or a message token is provided, which is used to retrieve the message.
- MQCB can be used to define callback routines before starting consumption with MQCTL or it can be used from within a callback routine.
- To use MQCB from outside of a callback routine, we must first suspend message consumption by using MQCTL and resume consumption afterward.
- MQCB is not supported within the IMS adapter.
Message consumer callback sequence
We can configure a consumer to invoke callback at key points during the lifecycle of the consumer. For example:- when the consumer is first registered,
- when the connection is started,
- when the connection is stopped and
- when the consumer is deregistered, either explicitly, or implicitly by an MQCLOSE.
Verb | Meaning |
---|---|
MQCTL(START) | MQCTL call using the MQOP_START Operation |
MQCTL(STOP) | MQCTL call using the MQOP_STOP Operation |
MQCTL(WAIT) | MQCTL call using the MQOP_START_WAIT Operation |
- REGISTER
- Is always the first type of invocation of the callback.
- START
- Is always called synchronously with the MQCTL(START) verb.
- All START callbacks are completed before the MQCTL(START) verb returns.
- STOP
- No further messages or events are delivered after this call until the connection is restarted.
- DEREGISTER
- Is always the last type of invocation of the callback.
Ensure that the application performs thread-based initialization and cleanup in the START and STOP callbacks. We can do non-thread based initialization and cleanup with REGISTER and DEREGISTER callbacks.
Do not make any assumptions about the life and availability of the thread other than what is stated. For example, do not rely on a thread staying alive beyond the last call to DEREGISTER. Similarly, when you have chosen not to use THREAD_AFFINITY, do not assume that the thread exists whenever the connection is started.
If the application has particular requirements for thread characteristics, it can always create a thread accordingly, then use MQCTL(WAIT). This has the effect of 'donating' the thread to IBM MQ for asynchronous message delivery.
Message consumer connection usage
We can configure a consumer to invoke callback at key points during the lifecycle of the consumer. For example:- when the consumer is first registered,
- when the connection is started,
- when the connection is stopped and
- when the consumer is deregistered, either explicitly, or implicitly by an MQCLOSE.
Verb | Meaning |
---|---|
MQCTL(START) | MQCTL call using the MQOP_START Operation |
MQCTL(STOP) | MQCTL call using the MQOP_STOP Operation |
MQCTL(WAIT) | MQCTL call using the MQOP_START_WAIT Operation |
- REGISTER
- Is always the first type of invocation of the callback.
- START
- Is always called synchronously with the MQCTL(START) verb.
- All START callbacks are completed before the MQCTL(START) verb returns.
- STOP
- No further messages or events are delivered after this call until the connection is restarted.
- DEREGISTER
- Is always the last type of invocation of the callback.
Ensure that the application performs thread-based initialization and cleanup in the START and STOP callbacks. We can do non-thread based initialization and cleanup with REGISTER and DEREGISTER callbacks.
Do not make any assumptions about the life and availability of the thread other than what is stated. For example, do not rely on a thread staying alive beyond the last call to DEREGISTER. Similarly, when you have chosen not to use THREAD_AFFINITY, do not assume that the thread exists whenever the connection is started.
If the application has particular requirements for thread characteristics, it can always create a thread accordingly, then use MQCTL(WAIT). This has the effect of 'donating' the thread to IBM MQ for asynchronous message delivery.
C invocation
MQCB (Hconn, Operation, CallbackDesc, Hobj, MsgDesc, GetMsgOpts, &CompCode, &Reason);Declare the parameters as follows:
MQHCONN Hconn; /* Connection handle */ MQLONG Operation; /* Operation being processed */ MQCBD CallbackDesc; /* Callback descriptor */ MQHOBJ HObj /* Object handle */ MQMD MsgDesc /* Message descriptor attributes */ MQGMO GetMsgOpts /* Message options */ MQLONG CompCode; /* Completion code */ MQLONG Reason; /* Reason code qualifying CompCode */
COBOL invocation
CALL 'MQCB' USING HCONN, OPERATION, CBDESC, HOBJ, MSGDESC, GETMSGOPTS, COMPCODE, REASON.Declare the parameters as follows:
** Connection handle 01 HCONN PIC S9(9) BINARY. ** Operation 01 OPERATION PIC S9(9) BINARY. ** Callback Descriptior 01 CBDESC. COPY CMQCBDV. 01 HOBJ PIC S9(9) BINARY. ** Message Descriptior 01 MSGDESC. COPY CMQMDV. ** Get Message Options 01 GETMSGOPTS. COPY CMQGMOV. ** Completion code 01 COMPCODE PIC S9(9) BINARY. ** Reason code qualifying COMPCODE 01 REASON PIC S9(9) BINARY.
PL/I invocation
call MQCB(Hconn, Operation, CallbackDesc, Hobj, MsgDesc, GetMsgOpts, CompCode, Reason)Declare the parameters as follows:
dcl Hconn fixed bin(31); /* Connection handle */ dcl Operation fixed bin(31); /* Operation */ dcl CallbackDesc like MQCBD; /* Callback Descriptor */ dcl Hobj fixed bin(31); /* Object Handle */ dcl MsgDesc like MQMD; /* Message Descriptor */ dcl GetMsgOpts like MQGMO; /* Get Message Options */ dcl CompCode fixed bin(31); /* Completion code */ dcl Reason fixed bin(31); /* Reason code qualifying CompCode */Parent topic: Function calls