Theme
One of the common mistakes that people make when they first start programming with the MQI can be seen in this pseudo-code example:
MQMD md = {MQMD_DEFAULT} MQGMO gmo = {MQGMO_DEFAULT} int bufsize = 128 PMQCHAR buf = malloc(bufsize) do { MQGET(&md,&gmo,buf,bufsize)) } while (rc != MQRC_NO_MSG_AVAILABLE)
They complain that despite pre-loading the queue, only a single message is returned. Anyone reading this is likely to recognise immediately the problem: the MsgId of the first message is returned in the md
variable. The next iteration of the loop tries to match that MsgID and doesn’t find any more messages.
There are aspects of the MQI that try to minimise your chances of getting this wrong, like the MatchOptions
flag in the MQGMO structure. But that in turn requires you know a) to set it and b) override the default version of the structure.
Having worked with MQ for so many years, I am hopefully not going to make that kind of mistake. But I still got caught out recently by a very similar problem.
Variation
The pseudo-code for my program looks like this:
MQMD md = {MQMD_DEFAULT} MQGMO gmo = {MQGMO_DEFAULT} int bufsize = 128 PMQCHAR buf gmo.Options = MQGMO_CONVERT do { bufsize = bufsize*2 buf = malloc(bufsize) // Increase the buffer on each loop MQGET(&md,&gmo, buf, bufsize) } while (rc == MQRC_TRUNCATED_MSG_FAILED)
This again is not the real compilable code but it should explain the principle. So you can ignore the apparent memory leak. The idea is that since we don’t know how big the message is, we keep enlarging the data buffer until we can get the full message. And my system behaved as expected when I tested it.
But I got reports of corrupt message data when the program ran as a client to a z/OS system. It was very easy to debug once I reproduced the environment. It – annoyingly and perhaps embarrassingly – turned out to be a lot like the MsgId problem. The returned md
variable is modified not only with the MsgId but also with the CodedCharSetId (codepage) and Encoding (endianness) of the message even when the MQGET fails. Since I wasn’t resetting the md
contents inside the loop, the second attempt asks for the data to be converted into its own codepage and endianness. So the message data is not in fact converted, and hence it looks corrupt.
Coda
This was very easy to fix once I’d diagnosed the problem. But I’ve not seen this specific issue before, so perhaps this can be a warning to others.
This post was last updated on September 20th, 2021 at 08:17 am