Getting a message using signaling

 

Signaling is available only with WebSphere MQ for z/OS.

This example demonstrates how to use the MQGET call to set a signal so that you are notified when a suitable message arrives on a queue. This extract is not taken from the sample applications supplied with WebSphere MQ.


⋮
get_set_signal()
{
     MQMD    MsgDesc;
     MQGMO   GetMsgOpts;
     MQLONG  CompCode;
     MQLONG  Reason;
     MQHCONN Hconn;
     MQHOBJ  Hobj;
     MQLONG  BufferLength;
     MQLONG  DataLength;
     char message_buffer[100];
     long  int q_ecb, work_ecb;
     short int signal_sw, endloop;
     long  int mask = 255;
 
     /*---------------------------*/
     /*  Set up GMO structure.    */
     /*---------------------------*/
     memset(&GetMsgOpts,'\0',sizeof(GetMsgOpts));
     memcpy(GetMsgOpts.StrucId, MQGMO_STRUC_ID,
            sizeof(GetMsgOpts.StrucId);
     GetMsgOpts.V     = MQGMO_VERSION_1;
     GetMsgOpts.WaitInterval = 1000;
     GetMsgOpts.Options      = MQGMO_SET_SIGNAL +
                               MQGMO_BROWSE_FIRST;
     q_ecb              = 0;
     GetMsgOpts.Signal1      = &q_ecb;
     /*---------------------------*/
     /*  Set up MD structure.     */
     /*---------------------------*/
     memset(&MsgDesc,'\0',sizeof(MsgDesc));
     memcpy(MsgDesc.StrucId, MQMD_STRUC_ID,
            sizeof(MsgDesc.StrucId);
     MsgDesc.V = MQMD_VERSION_1;
     MsgDesc.Report   = MQRO_NONE;
     memcpy(MsgDesc.MsgId,MQMI_NONE,
            sizeof(MsgDesc.MsgId));
     memcpy(MsgDesc.CorrelId,MQCI_NONE,
            sizeof(MsgDesc.CorrelId));
    /*---------------------------------------------------*/
    /*  Issue the MQGET call.                            */
    /*---------------------------------------------------*/
     BufferLength = sizeof(message_buffer);
     signal_sw   = 0;
 
     MQGET(Hconn, Hobj, &MsgDesc, &GetMsgOpts,
           BufferLength, message_buffer, &DataLength,
           &CompCode, &Reason);
    /*-------------------------------------*/
    /*  Check completion and reason codes. */
    /*-------------------------------------*/
     switch (CompCode)
         {
          case (MQCC_OK):          /* Message retrieved  */
              break;
          case (MQCC_WARNING):
              switch (Reason)
              {
               case (MQRC_SIGNAL_REQUEST_ACCEPTED):
                   signal_sw = 1;
                   break;
               default:
                   break;   /* Perform error processing  */
              }
              break;
          case (MQCC_FAILED):
              switch (Reason)
              {
               case (MQRC_Q_MGR_NOT_AVAILABLE):
               case (MQRC_CONNECTION_BROKEN):
               case (MQRC_Q_MGR_STOPPING):
                   break;
               default:
                   break;  /* Perform error processing.  */
              }
              break;
          default:
              break;       /* Perform error processing.  */
         }
    /*---------------------------------------------------*/
    /* If the SET_SIGNAL was accepted, set up a loop to  */
    /* check whether a message has arrived at one second */
    /* intervals. The loop ends if a message arrives or  */
    /* the wait interval specified in the MQGMO          */
    /* structure has expired.                            */
    /*                                                   */
    /* If a message arrives on the queue, another MQGET  */
    /* must be issued to retrieve the message. If other  */
    /* MQM calls have been made in the intervening       */
    /* period, this may necessitate reinitializing the   */
    /* MQMD and MQGMO structures.                        */
    /* In this code, no intervening calls                */
    /* have been made, so the only change required to    */
    /* the structures is to specify MQGMO_NO_WAIT,       */
    /* since we now know the message is there.           */
    /*                                                   */
    /* This code uses the EXEC CICS DELAY command to     */
    /* suspend the program for a second. A batch program */
    /* may achieve the same effect by calling an         */
    /* assembler language subroutine which issues a      */
    /* z/OS STIMER macro.                                */
    /*---------------------------------------------------*/
    if (signal_sw == 1)
       {
        endloop = 0;
        do
          {
           EXEC CICS DELAY FOR HOURS(0) MINUTES(0) SECONDS(1);
           work_ecb = q_ecb & mask;
           switch (work_ecb)
               {
                case (MQEC_MSG_ARRIVED):
                    endloop = 1;
                    mqgmo_options = MQGMO_NO_WAIT;
                    MQGET(Hconn, Hobj, &MsgDesc, &GetMsgOpts,
                          BufferLength, message_buffer,
                          &DataLength, &CompCode, &Reason);
                    if (CompCode != MQCC_OK)
                        ;          /* Perform error processing. */
                    break;
                case (MQEC_WAIT_INTERVAL_EXPIRED):
                case (MQEC_WAIT_CANCELED):
                    endloop = 1;
                    break;
                default:
                    break;
               }
          } while (endloop == 0);
       }
     return;
}

 

Parent topic:

C language examples


fg18900_