Getting a message using signaling
Signaling is available only with IBM® 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 IBM 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.Version = 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.Version = 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;
}