HOWTO: Memory Handling Tips for MQ Asynchronous Application

ID: Q173653

The information in this article applies to:

SUMMARY

When you are using MQReceiveMessage with a callback function in Microsoft Message Queue Server (MSMQ), you should make sure to allocate the MQMSGPROPS structure properly and always close the queue before exiting your application. Improper allocation of MQMSGPROPS can cause memory corruption or error messages. Closing the queue causes any pending Receive operations to fail and call your callback function, where you can delete the MQMSGPROPS structure you've allocated.

MORE INFORMATION

When you are using a callback function as an asynchronous mechanism for MQReceiveMessage, you should be careful in how you allocate and later deallocate the MQMSGPROPS structure used in the MQReceiveMessage call.

First, you need to make sure to allocate the structure memory on the heap instead of the stack. For example, the following will not work:

   HRESULT CallReceive()
   {
      MQMSGPROPS Props;
      ...  //Allocate the properties
      return MQReceiveMessage(..., &Props, ...);
   };

Since Props was allocated inside the function call, its memory will likely be freed before the callback function is called. This can cause Access Violations, General Protection Faults, or memory corruption when MSMQ or your callback function attempts to use the structure. Them following shows a more appropriate method:

   HRESULT CallReceive()
   {
      MQMSGPROPS* pProps = malloc(sizeof(MQMSGPROPS));
      ... //Allocate the Properties
      HRESULT hr = MQReceiveMessage(..., pProps, ..., &ReceiveCallback,
         ...);
      if (FAILED(hr))
         free(pProps);
      return hr;
   };

   void ReceiveCallback(HRESULT hrStatus, ...,MQMSGPROPS*
pMessageProps,...)
   {
      ... // Process the message
      free(pMessageProps);
   };

You should free the MQMSGPROPS structure in your callback function. You should also make sure that if the original MQReceiveMessage fails, the structure is disposed of properly.

Second, you should make sure to always call MQCloseQueue prior to closing your application. When you call MQCloseQueue all of the pending Receive operations cause your callback function to be called with the hrStatus member set to MQ_ERROR_OPERATION_CANCELLED. If you do not close the queue before exiting, any MQMSGPROPS structures associated with a pending Receive operation will not be freed.

REFERENCES

Microsoft Message Queue Server Help

Keywords          : kbcode MQQueue 
Version           : WinNT:1.0
Platform          : winnt
Issue type        : kbhowto

Last Reviewed: September 23, 1997