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® WebSphere® MQ when certain events occur.

To use MQCB and MQCTL on a V7 client you must be connected to a V7 server and the SHARECNV parameter of the channel must have 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, and on IBM i for applications running in compatibility mode, you 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. You must specify one of the following options; if more than one option is required, the values can be:
  • Added (do not add the same constant more than once), or
  • Combined 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.

You 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 you 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.
This prevents the consumer from polling in a busy loop when a zero wait interval is specified.
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

  1. 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.
  2. MQCB can be used to define callback routines before starting consumption with MQCTL or it can be used from within a callback routine.
  3. To use MQCB from outside of a callback routine, you must first suspend message consumption by using MQCTL and resume consumption afterward.
  4. MQCB is not supported within the IMS adapter.

Message consumer callback sequence

You 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.
Table 1. MQCTL verb definitions
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
This allows the consumer to maintain state associated with the consumer. When a callback is requested by an application, the rules for consumer invocation are as follows:
REGISTER
Is always the first type of invocation of the callback.
Is always called on the same thread, as the MQCB(REGISTER) call.
START
Is always called synchronously with the MQCTL(START) verb.
  • All START callbacks are completed before the MQCTL(START) verb returns.
Is on the same thread as the message delivery if THREAD_AFFINITY is requested.
The call with start is not guaranteed if, for example, a previous callback issues MQCTL(STOP) during the MQCTL(START).
STOP
No further messages or events are delivered after this call until the connection is restarted.
A STOP is guaranteed if the application was previously called for START, or a message, or an event.
DEREGISTER
Is always the last type of invocation of the callback.

Ensure that your application performs thread-based initialization and cleanup in the START and STOP callbacks. You 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 your 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 WebSphere MQ for asynchronous message delivery.

Message consumer connection usage

You 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.
Table 2. MQCTL verb definitions
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
This allows the consumer to maintain state associated with the consumer. When a callback is requested by an application, the rules for consumer invocation are as follows:
REGISTER
Is always the first type of invocation of the callback.
Is always called on the same thread, as the MQCB(REGISTER) call.
START
Is always called synchronously with the MQCTL(START) verb.
  • All START callbacks are completed before the MQCTL(START) verb returns.
Is on the same thread as the message delivery if THREAD_AFFINITY is requested.
The call with start is not guaranteed if, for example, a previous callback issues MQCTL(STOP) during the MQCTL(START).
STOP
No further messages or events are delivered after this call until the connection is restarted.
A STOP is guaranteed if the application was previously called for START, or a message, or an event.
DEREGISTER
Is always the last type of invocation of the callback.

Ensure that your application performs thread-based initialization and cleanup in the START and STOP callbacks. You 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 your 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 WebSphere 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 */