This topic describes how to receive messages from an inactive call message queue.
Occasionally there is a need to receive messages from the job log that were sent to a call message queue which is no longer active. For example, PGMA calls PGMB, PGMB sends a diagnostic message to itself and an escape message to PGMA. PGMA can easily receive the escape message that was sent to it, but sometimes it necessary to also receive the diagnostic message. Since the diagnostic is on a call message queue that is no longer active, the message must be received by using a message reference key. This can be done, but it takes more work than one simple receive message command.
The following considerations are important in understanding how this works:
The following steps are required to obtain a message from a program or procedure that has ended:
A sample program of the procedure described above is provided below using the RCVMSG command and the QMHRCVPM API.
******************************************************************************* * * CL program example using the RCVMSG command * * ******************************************************************************* This has the advantage of being easier to code and is easier to follow. It has the disadvantage of requiring the program to monitor for and handle the CPF2410 exception, which is not a good thing if performance is important. PGM DCL &LOWKEY *CHAR 4 DCL &HIKEY *CHAR 4 DCL &MSGKEY *CHAR 4 DCL &MSG *CHAR 256 /*-----------------------------------------------------------------*/ /* OBTAIN STARTING MESSAGE REFERENCE KEY */ /*-----------------------------------------------------------------*/ SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&LOWKEY) RMVMSG MSGKEY(&LOWKEY) /*-----------------------------------------------------------------*/ /* EXECUTE FUNCTION */ /*-----------------------------------------------------------------*/ ---- Insert whatever command(s) or program call(s) you want ---- ---- to handle messages for here ---- /*-----------------------------------------------------------------*/ /* OBTAIN ENDING MESSAGE REFERENCE KEY */ /*-----------------------------------------------------------------*/ SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&HIKEY) RMVMSG MSGKEY(&HIKEY) /*-----------------------------------------------------------------*/ /* LOOP TO RECEIVE MESSAGES ON INACTIVE INVOCATION */ /*-----------------------------------------------------------------*/ CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&LOWKEY 1 4) + 1) LOOP: RCVMSG PGMQ(*SAME (*)) MSGKEY(&MSGKEY) RMV(*NO) MSG(&MSG) MONMSG CPF2410 EXEC(DO) /* HANDLE MSGKEY NOT FOUND */ RCVMSG MSGTYPE(*EXCP) RMV(*YES) /* REMOVE UNWANTED EXCEPTION */ GOTO SKIP ENDDO ---- Insert code here to do whatever processing is needed ---- ---- for the message. You may need to add additional ---- ---- values, such as message ID, message type, etc., to ---- ---- the RCVMSG command. ---- SKIP: CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&MSGKEY 1 4) + 1) IF (&MSGKEY *LT &HIKEY) GOTO LOOP ENDPGM ******************************************************************************* * * CL program using the QMHRCVPM API. * ******************************************************************************* This sample is similar to the first sample. The only difference is that it uses the QMHRCVPM API instead of the RCVMSG CL command. By using the error code structure, it eliminates the need to handle the CPF2410 exception and the overhead required to send the exception in the case of the message key not being found. This example shows how to extract the message text from the structure returned by the API. If the message is an immediate message (i.e. no message ID), the message is in the 'Replacement data or impromptu message text' area; otherwise it is in the 'Message' area which follows the 'Replacement data' field. The example checks the message length to determine which of these fields to use for the message. PGM DCL &LOWKEY *CHAR 4 DCL &HIKEY *CHAR 4 DCL &MSGKEY *CHAR 4 DCL &MSG *CHAR 256 /*------------------------------------------------------------------*/ /* Some messages have a large amount of message data, in which case */ /* the size of the &MSGINFO variable will not be adequate. If you */ /* expect to receive messages with a large amount of message data, */ /* you will need to increase the size of this variable accordingly. */ /* Be sure to also change the value that is put into &MSGINFOL to */ /* reflect the size of the variable. */ /*------------------------------------------------------------------*/ DCL &MSGINFO *CHAR 1000 DCL &MSGINFOL *CHAR 4 DCL &ERRCODE *CHAR 16 DCL &MSGOFFS *DEC (4 0) DCL &MSGLEN *DEC (4 0) /*-----------------------------------------------------------------*/ /* OBTAIN STARTING MESSAGE REFERENCE KEY */ /*-----------------------------------------------------------------*/ SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&LOWKEY) RMVMSG MSGKEY(&LOWKEY) /*-----------------------------------------------------------------*/ /* EXECUTE FUNCTION */ /*-----------------------------------------------------------------*/ ---- Insert whatever command(s) or program call(s) you want ---- ---- to handle messages for here ---- /*-----------------------------------------------------------------*/ /* OBTAIN ENDING MESSAGE REFERENCE KEY */ /*-----------------------------------------------------------------*/ SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&HIKEY) RMVMSG MSGKEY(&HIKEY) /*-----------------------------------------------------------------*/ /* LOOP TO RECEIVE MESSAGES WITH QMHRCVPM API */ /*-----------------------------------------------------------------*/ CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&LOWKEY 1 4) + 1) CHGVAR %BIN(&MSGINFOL 1 4) 1000 CHGVAR %BIN(&ERRCODE 1 4) 16 LOOP2: CALL QMHRCVPM (&MSGINFO &MSGINFOL RCVM0200 '* ' + X'00000000' '*ANY ' &MSGKEY X'00000000' + '*SAME ' &ERRCODE) IF ((%BIN(&MSGINFO 5 4) *GT 0) *AND (%BIN(&ERRCODE 5 4) *EQ 0)) + DO /* IF A MESSAGE WAS RECEIVED */ IF (%BIN(&MSGINFO 161 4) *EQ 0) + DO /* IMPROMPTU MESSAGE */ CHGVAR &MSGLEN %BIN(&MSGINFO 153 4) CHGVAR &MSGOFFS 177 ENDDO ELSE + DO /* STORED MESSAGE */ CHGVAR &MSGLEN %BIN(&MSGINFO 161 4) CHGVAR &MSGOFFS (177 + %BIN(&MSGINFO 153 4)) ENDDO CHGVAR &MSG %SST(&MSGINFO &MSGOFFS &MSGLEN) ---- Insert code here to do whatever processing is needed ---- ---- for the message. You can extract additional ---- ---- values, such as message ID, message type, etc., ---- ---- from the message information structure if necessary. ---- ENDDO CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&MSGKEY 1 4) + 1) IF (&MSGKEY *LT &HIKEY) GOTO LOOP2 ENDPGM