Sun logo      Previous      Contents      Index      Next     

Sun ONE Message Queue 3.5 C Client Developer's Guide

Chapter 3
Using the C API

This chapter describes how to use C functions to accomplish specific tasks and provides brief code samples to illustrate some of these tasks. (For clarity, the code examples shown in the following sections omit a function call status check.)

Following a brief discussion of overall design and a summary of client tasks, the topics covered include the following:

This chapter does not provide exhaustive information about each function. For detailed function information, please see the description of that function in Chapter 4, "Reference".

For information on building MQ C programs, see Chapter 2, "Building and Running MQ C Clients".


MQ C Client Setup Operations

The general procedures for producing and consuming messages are introduced below. The procedures have a number of common steps which need not be duplicated if a client is both producing and consuming messages.

    To Set Up an MQ C Client to Produce Messages
  1. Call the MQCreateProperties function to get a handle to a properties object.
  2. Use one or more of the MQSet... Property functions to set connection properties that specify the name of the broker, its port number, and its behavior.
  3. Use the MQCreateConnection function to create a connection.
  4. Use the MQCreateSession function to create a session and to specify its acknowledge mode and its receive mode. If the session will be used only for producing messages, use the receive mode MQ_SESSION_SYNC_RECEIVE to avoid creating a thread for asynchronous message delivery.
  5. Use the MQCreateDestination function to specify a physical destination on the broker. The destination name you specify must be the same as the name of the physical destination.
  6. Use the MQCreateMessageProducer function or the MQCreateMessageProducerForDestination function to create a message producer. (If you plan to send a lot of messages to the same destination, you should use the MQCreateMessageProducerForDestination function.)
  7. Use the MQCreateBytesMessage function or the MQCreateTextMessage function to get a newly created message handle.
  8. Call the MQCreateProperties function to get a handle to a properties object that will describe the message header properties. This is only required if you want to set a message header property.
  9. Use one or more of the MQSet... Property functions to set properties that specify the value of the message header properties you want to set.
  10. Use the MQSetMessageHeaders function, passing a handle to the properties object you created in Step 8 and Step 9.
  11. Repeat Step 8 if you want to define custom message properties, and then use the MQSetMessageProperties function to set these properties for your message.
  12. Use the MQSetMessageReplyTo function if you want to specify a destination where replies to the message are to be sent.
  13. Use one of the MQSendMessage... functions to send the message.
    To Set Up an MQ C Client to Consume Messages Synchronously
  1. Call the MQCreateProperties function to get a handle to a properties object.
  2. Use one or more of the MQSet... Property functions to set connection properties that specify the name of the broker, its port number, and its behavior.
  3. Use the MQCreateConnection function to create a connection.
  4. Use the MQCreateSession function to create a session and to specify its receive mode. Specify MQ_SESSION_SYNC_RECEIVE for a synchronous session.
  5. Use the MQCreateDestination function to specify a destination on the broker from which the consumer is to receive messages. The destination name you specify must be the same as the name of the physical destination.
  6. Use the MQCreateMessageConsumer function or the MQCreateDurableMessageConsumer function to create a consumer.
  7. Use the MQStartConnection function to start the connection.
  8. Use one of the MQReceiveMessage... functions to start message delivery.
    To Set Up an MQ C Client to Consume Messages Asynchronously
  1. Call the MQCreateProperties function to get a handle to a properties object.
  2. Use one or more of the MQSet... Property functions to set connection properties that specify the name of the broker, its port number, and its behavior.
  3. Use the MQCreateConnection function to create a connection.
  4. Use the MQCreateSession function to create a session and to specify its acknowledge mode and its receive mode. Specify MQ_SESSION_ASYNC_RECEIVE for asynchronous message delivery.
  5. Use the MQCreateDestination function to specify a destination on the broker from which the consumer is to receive messages. The logical destination name you specify must be the same as the name of the physical destination.
  6. Write a callback function of type MQMessageListenerFunc that will be called when the broker starts message delivery. In the body of this callback function, use the functions listed in Table 3-9, to process the contents of the incoming message.
  7. Use the MQCreateAsyncMessageConsumer function or the MQCreateAsyncDurableMessageConsumer function to create a consumer.
  8. Use the MQStartConnection function to start the connection and message delivery.


Working With Properties

When you create a connection, set message header properties, or set user-defined message properties, you must pass a handle to a properties object. You use the MQCreateProperties function to create this object and to obtain a handle to it. When you receive a message, you can use specific MQGet...Property functions to obtain the type and value of each message property.

This section describes the functions you use to set and get properties. A property is defined as a key-value pair.

Setting Connection and Message Properties

You use the functions listed in Table 3-1 to create a handle to a properties object, and to set properties. You can use these functions to create and define properties for connections or for individual messages.

Table 3-1  Functions Used to Set Properties 

Function

Description

MQCreateProperties

Creates a properties object and passes back a handle to it.

MQSetBoolProperty

Sets an MQBool property.

MQSetStringProperty

Sets an MQString property.

MQSetInt8Property

Sets an MQInt8 property.

MQSetInt16Property

Sets an MQInt16 property.

MQSetInt32Property

Sets an MQInt32 property.

MQSetInt64Property

Sets an MQInt64 property.

MQSetFloat32Property

Sets an MQFloat32 property.

MQSetFloat64Property

Sets an MQFloat64 property.

    To Set Properties for a Connection
  1. Call the MQCreateProperties function to get a handle to a newly created properties object.
  2. Call one of the MQSet...Property functions to set one of the connection properties listed in Table 4-2. At a minimum, you must specify the name of the host of the broker to which you want to connect and its port number.
  3. Which function you call depends on the type of the property you want to set; for example, to set an MQString property, you call the MQSetStringProperty function; to set an MQBool property, you call the MQSetBoolProperty function; and so on. Each function that sets a property requires that you pass a key name and value; these are listed and described in Table 4-2.

  4. When you have set all the properties you want to define for the connection, you can then create the connection, by calling the MQCreateConnection function.

Once the connection is created with the properties you specify, you cannot change its properties. If you need to change connection properties after you have created a connection, you will need to destroy the old connection and its associated objects and create a new one with the desired properties. It is a good idea to think through the desired behavior before you create a connection.

Code Example 3-1 illustrates how you create a properties handle and how you use it for setting connection properties.

Code Example 3-1  Setting Connection Properties 

MQStatus status;

MQPropertiesHandle propertiesHandle = MQ_INVALID_HANDLE;

status = (MQCreateProperties(&propertiesHandle);

status = (MQSetStringProperty(propertiesHandle,
           MQ_BROKER_HOST_PROPERTY, “localhost”));

status = (MQSetInt32Property(propertiesHandle,
           MQ_BROKER_PORT_PROPERTY, 7676));

status = MQSetStringProperty(propertiesHandle,
          MQ_CONNECTION_TYPE_PROPERTY, “TCP”));

The MQ C client runtime sets the connection properties that specify the name and version of the MQ product; you can retrieve these using the MQGetMetaData function. These properties are described at the end of Table 4-2, starting with MQ_NAME_PROPERTY.

    To Set Message Properties

Set message properties and message header properties using the same procedure you used to set connection properties. You can set the following message header properties for sending a message:

For more information, see MQSetMessageProperties.

Getting Message Properties

When you receive a message, if you are interested in the message properties, you need to obtain a handle to the properties object associated with that message:

Having obtained the handle, you can then iterate through the properties and then use the appropriate MQGet...Property function to determine the type and value of each property.

Table 3-2 lists the functions you use to iterate through a properties handle and to obtain the type and value of each property.

Table 3-2  Functions Used to Get Message Properties 

Function

Description

MQPropertiesKeyIterationStart

Starts the iteration process through the specified properties handle

MQPropertiesKeyIterationHasNext

Returns MQ_TRUE if there are additional property keys left in the iteration.

MQPropertiesKeyIterationGetNext

Passes back the address of the next property key in the referenced property handle.

MQGetPropertyType

Gets the type of the specified property.

MQGetBoolProperty

Gets the value of the specified MQBool type property.

MQGetStringProperty

Gets the value of the specified MQString type property.

MQGetInt8Property

Gets the value of the specified MQInt8 type property.

MQGetInt16Property

Gets the value of the specified MQInt16 type property.

MQGetInt32Property

Gets the value of the specified MQInt16 type property.

MQGetInt32Property

Gets the value of the specified MQInt32 type property.

MQGetInt64Property

Gets the value of the specified MQInt64 type property.

MQGetFloat32Property

Gets the value of the specified MQFloat32 type property.

MQGetFloat64Property

Gets the value of the specified MQFloat64 type property.

    To Iterate Through a Properties Handle
  1. Start the process by calling the MQPropertiesKeyIterationStart function.
  2. Loop using the MQPropertiesKeyIterationHasNext function.
  3. Extract the name of each property key by calling the MQPropertiesKeyIterationGetNext function.
  4. Determine the type of the property value for a given key by calling the MQGetPropertyType function.
  5. Use the appropriate MQGet...Property function to find the value of the specified property key and type.

If you know the property key, you can just use the appropriate MQGet...Property function to get its value. Code Example 3-2 illustrates how you implement these steps.

Code Example 3-2  Getting Property Values for a Message Header

MQStatus status;

MQPropertiesHandle headersHandle = MQ_INVALID_HANDLE;

MQBool redelivered;

ConstMQString my_msgtype;

status = (MQGetMessageHeaders(messageHandle, &headersHandle));

status = (MQGetBoolProperty(headersHandle,
           MQ_REDELIVERED_HEADER_PROPERTY, &redelivered));

status = MQGetStringProperty(headersHandle,
          MQ_MESSAGE_TYPE_HEADER_TYPE_PROPERTY, &my_msgtype);


Working With Connections

All messaging occurs within the context of a connection: the behavior of the connection is defined by the properties set for that connection. These properties specify the following information:

You use the functions listed in Table 3-3 to create, start, stop, and close a connection.

Table 3-3  Functions Used to Work with Connections 

Function

Description

MQInitializeSSL

Initializes the SSL library. You must call this function before you create any connection that uses SSL.

MQCreateConnection

Creates a connection and passes back a handle to it.

MQStartConnection

Starts the specified connection and starts or resumes delivery of messages.

MQStopConnection

Stops the specified connection.

MQGetMetaData

Returns a handle to name and version information for the MQ product.

MQCloseConnection

Closes the specified connection.

Before you create a connection, you must do the following:

When you have completed these steps, you are ready to call MQCreateConnection to create a connection. After you create the connection, you can create a session as described in "Working With Sessions and Destinations".

When you send a message, you do not need to start the connection explicitly by calling MQStartConnection. You do need to call MQStartConnection before the broker can deliver messages to a consumer.

If you need to halt delivery in the course of processing messages, you can call the MQStopConnection function.

Working With Secure Connections

To set up a secure connection, you need to call the MQInitializeSSl function once (and only once) before you call the MQCreateConnection function, and you must set the MQ_CONNECTION_TYPE_PROPERTY to SSL. Depending on the operating system, you might also need to locate or create NSS certificate database files.

The MQInitializeSSl function initializes the NSS library. The certificateDatabasePath parameter you pass to the MQInitializeSSL function should point to a directory that contains the NSS files certN.db, keyN.db, and secmod.db (where N is a numeric digit). These certificate database files are opened read-only by the MQInitializeSSL function. You can generate the NSS certificate database files by using the Netscape or Mozilla browser. You can find the NSS certificate database files in the directory where the Netscape or Mozilla browser stores user settings, preferences, and bookmarks. For Mozilla, these files might not be created automatically. In that case, you can have them created by doing the following:

  1. Start the Mozilla browser.
  2. Choose Edit > Private & Security > Certificates
  3. Click the Manager Certificates... button.

Solaris 8 or 9 comes with the Netscape browser, as does RedHat Linux. For Windows, you can download the Mozilla browser 1.5 from the following location:

http://www.mozilla.org/

After you call the MQInitializeSSL function, you can call MQCreateConnection to create an SSL connection to the MQ broker by setting the connection property MQ_CONNECTION_TYPE_PROPERTY to SSL. Setting the connection property MQ_SSL_BROKER_IS_TRUSTED to MQ_TRUE (the default is MQ_FALSE) is not tested or supported in this release. Before running your MQ C client application over SSL, you should configure the MQ broker to enable SSL-based connection services. See the MQ Administrator’s Guide for instructions on configuring the broker.

Shutting Down Connections

In order to do an orderly shutdown, you need to close the connection by calling MQCloseConnection and then to free the memory associated with the connection by calling the MQFreeConnection function.

To get information about a connection, call the MQGetMetaData function. This returns name and version information for the MQ product.


Working With Sessions and Destinations

A session is a single-threaded context for producing and consuming messages. You can create multiple producers and consumers for a session, but you are restricted to using them serially. In effect, only a single logical thread of control can use them.

Table 3-4 describes the functions you use to create and manage sessions.

Table 3-4  Functions Used to Work with Sessions

Function

Description

MQCreateSession

Creates the specified session and passes back a handle to it.

MQGetAcknowledgeMode

Passes back the acknowledgement mode of the specified session.

MQRecoverSession

Stops message delivery and restarts message delivery with the oldest unacknowledged message. (For non-transacted sessions.)

MQRollBackSession

Rolls back a transaction associated with the specified session.

MQCommitSession

Commits a transaction associated with the specified session.

MQCloseSession

Closes the specified session.

Creating a Session

The MQCreateSession function creates a new session and initializes a handle to it in the sessionHandle parameter. The number of sessions you can create for a single connection is limited only by system resources. You can create a session after you have created a connection.

When you create a session, you specify whether it’s transacted, the acknowledge mode, and the receive mode. After you create a session, you can create the producers, consumers, and destinations that use the session context to do their work.

Transacted Sessions

If you specify that a session be transacted, the acknowledge mode is ignored. Within a transacted session, the broker tracks sends and receives, completing these operations only when the client issues a call to commit the transaction. If a send or receive operation fails, an exception is raised. Your application can handle the exception by ignoring it, retrying it, or rolling back the entire transaction. When a transaction is committed, all the successful operations are completed. When a transaction is rolled back, all successful operations are cancelled.

Message Acknowledgement

When a message is delivered to a receiving client, the broker waits for the client to acknowledge receipt of a message before deleting the message from the broker’s destination.

The receiving client can control messaging reliability by setting the session’s acknowledge mode to one of the following values:

The setting of the connection property MQ_ACK_ON_ACKNOWLEDGE_PROPERTY also determines the effect of some of these acknowledge modes. For more information, see Table 4-2.

Receive Mode

You can specify a session’s receive mode as either MQ_SESSION_SYNC_RECEIVE or MQ_SESSION_ASYNC_RECEIVE. If the session you create will be used for sending messages only, you should specify MQ_SESSION_SYNC_RECEIVE for its receive mode for optimization because the asynchronous receive mode automatically allocates an additional thread for the delivery of messages it expects to receive.

Managing a Session

Managing a session involves using threads appropriately for the type of session (synchronous or asynchronous) and managing message delivery for both transacted and nontransacted sessions. For more information, see "Single-Threaded Session Control".

You can get information about a session’s acknowledgment mode by calling the MQGetAcknowledgeMode function.

Creating Destinations

After creating a session, you can create destinations or temporary destinations for the messages you want to send. Table 3-5 lists the functions you use to create and to get information about destinations.

Table 3-5  Functions Used to Work With Destinations 

Functions

Description

MQCreateDestination

Creates a destination and initializes a handle to it.

MQCreateTemporaryDestination

Creates a temporary destination and initializes a handle to it.

MQGetDestinationType

Returns the type (queue or topic) of the specified destination.

The MQCreateDestination function creates a destination object and passes a handle to it back to you. In a production environment, the MQ administrator has to also create a physical destination on the broker, whose name and type is the same as that of the destination object, in order for messaging to happen. For example, if you use the MQCreateDestination function to create a queue destination called myMailQDest, the administrator has to create a physical destination on the broker named myMailQDest.

By default, the imq.autocreate.topic and imq.autocreate.queue properties for the broker are turned on. In this case, which is more convenient in a development environment, the broker automatically creates a physical destination whenever a message consumer or message producer attempts to access a non-existent destination. The auto-created physical destination will have the same name as that of the destination you created using the MQCreateDestination function.

You use the MQCreateTemporaryDestination to create a temporary destination. You can use such a destination to implement a simple request/reply mechanism. When you pass the handle of a temporary destination to the MQSetMessageReplyTo function, the consumer of the message can use that handle as the destination to which it sends a reply.

Temporary destinations are explicitly created by client applications and are automatically deleted when the connection is closed. They are maintained (and named) by the broker only for the duration of the connection for which they are created. Temporary destinations are system-generated uniquely for their connection and only their own connection is allowed to create message consumers for them.

Use the MQGetDestinationType function to determine the type of a destination: queue or topic. There may be times when you don’t know the type of the destination to which you are replying: for example, when you get a handle from the MQGetMessageReplyTo function. Because the semantics of queue and topic destinations differ, you need to determine the type of a destination in order to reply appropriately.


Working With Messages

This section describes how you use the C-API to complete the following tasks:

Composing Messages

You can create either a text message or a bytes message. A message, whether text or bytes, is composed of a header, properties, and a body. Table 3-6 lists the functions you use to construct messages.

Table 3-6  Functions Used to Construct Messages 

Function

Description

MQCreateBytesMessage

Creates an MQ_BYTES_MESSAGE message.

MQCreateTextMessage

Creates an MQ_TEXT_MESSAGE message.

MQSetMessageHeaders

Sets message header properties. (Optional)

MQSetMessageProperties

Sets user-defined message properties.

MQSetStringProperty

Sets the body of an MQ_TEXT_MESSAGE message.

MQSetBytesMessageBytes

Sets the body of an MQ_BYTES_MESSAGE message.

MQSetMessageReplyTo

Specifies the destination where replies to this message should be sent.

You begin by creating a message using either the MQCreateBytesMessage function or the MQCreateTextMessage function. Either of these functions return a message handle that you can then pass to the functions you use to set the message body, header, and properties using the functions listed in Table 3-6.

When you set message header properties or when you set additional user-defined properties, you must pass a handle to a properties object that you have created using the MQCreateProperties function. For more information, see "Working With Properties".

You can use the MQSetMessageReplyTo function to associate a message with a destination that recipients can use for replies. To do this, you must first create a destination that will serve as your reply-to destination. Then, pass a handle to that destination when you call the MQSetMessageReplyTo function. The receiver of a message can use the MQGetMessageReplyTo function to determine whether a sender has set up a destination where replies are to be sent.

Sending a Message

Messages are sent by a message producer within the context of a connection and a session. Once you have obtained a connection, created a session, and composed your message, you can use the functions listed in Table 3-7 to create a message producer and to send the message.

Which function you choose to send a message depends on the following factors:

If you send a message using one of the functions that does not allow you to override header properties, the following message header fields are set to default values by the send method.

To override these values, use one of the extended send methods. For a complete list of message header properties, see Table 4-5.

Message headers also contain fields that can be set by the sending client; in addition, you can set user-defined message properties as well. For more information, see "Composing Messages".

You can set the broker property MQ_ACK_ON_PRODUCE_PROPERTY to make sure that the message has reached its destination on the broker:

Note that “acknowledgement” in this case is not programmatic but internally implemented. That is, the client thread is blocked and does not return until the broker acknowledges messages it receives.

An administrator can set a broker limit, REJECT_NEWEST, which allows the broker to avert memory problems by rejecting the newest incoming message. If the incoming message is persistent, than an exception is thrown which the sending client should handle, perhaps by re-trying the send a bit later. If the incoming message is not persistent, the client has no way of knowing that the broker rejected it. The broker might also reject a message if it exceeds a specified limit.

Receiving Messages

Messages are received by a message consumer in the context of a connection and a session. In order to receive messages, you must explicitly start the connection by calling the MQStartConnection function.

Table 3-8 lists the functions you use to create message consumers and to receive messages.

Table 3-8  Functions Used to Receive Messages 

Function

Description

MQCreateMessageConsumer

Creates the specified synchronous consumer and passes back a handle to it.

MQCreateDurableMessageConsumer

Creates a durable synchronous message consumer for the specified destination.

MQCreateAsyncMessageConsumer

Creates an asynchronous message consumer for the specified destination.

MQCreateAsyncDurableMessageConsumer

Creates a durable asynchronous message consumer for the specified destination.

MQUnsubscribeDurableMessageConsumer

Unsubscribes the specified durable message consumer.

MQReceiveMessageNoWait

Passes a handle back to a message delivered to the specified consumer if a message is available; otherwise it returns an error.

MQReceiveMessageWait

Passes a handle back to a message delivered to the specified consumer if a message is available; otherwise it blocks until a message becomes available.

MQReceiveMessageWithTimeout

Passes a handle back to a message delivered to the specified consumer if a message is available within the specified amount of time.

MQAcknowledgeMessages

Acknowledges the specified message and all messages received before it on the same session

MQCloseMessageConsumer

Closes the specified consumer.

Working With Consumers

When you create a consumer, you need to make several decisions:

A session’s consumers are automatically closed when you close the session or connection to which they belong. However, messages will be routed to the durable subscriber while it is inactive and delivered when a new durable consumer is recreated. To close a consumer without closing the session or connection to which it belongs, use the MQCloseMessageConsumer function. If you want to close a durable consumer permanently, you should call the function MQUnsubscribeDurableMessageConsumer after closing it, to delete state information maintained by the broker on behalf of the durable consumer.

Receiving a Message Synchronously

If you have created a synchronous consumer, you can use one of three receive functions: MQReceiveMessageNoWait, MQReceiveMessageWait, or MQReceiveMessagewithTimeOut. In order to use any of these functions, you must have specified MQ_SESSION_SYNC_RECEIVE for the receive mode when you created the session.

When you create a session you must specify one of several acknowledge modes for that session. If you specify MQ_CLIENT_ACKNOWLEDGE as the acknowledge mode for the session, you must explicitly call the MQAcknowledgeMessages function to acknowledge messages that you have received. If the session is transacted, the acknowledge mode parameter is ignored.

When the receiving function returns, it gives you a handle to the delivered message. You can pass that handle to the functions described in "Processing a Message", in order to read message properties and information stored in the header and body of the message.

Receiving a Message Asynchronously

To receive a message asynchronously, you must create an asynchronous message consumer and pass the name of an MQMessageListenerFunc type callback function. (Therefore, you must set up the callback function before you create the asynchronous consumer that will use it.) You should start the connection only after creating an asynchronous consumer. If the connection is already started, you should stop the connection before creating an asynchronous consumer.

You are also responsible for writing the message listener function. Mainly, the function needs to process the incoming message by examining its header, body, and properties, or it needs to pass control to a function that can do this processing. The client is also responsible for freeing the message handle (either from within the listener or from outside of the listener) by calling the MQFreeMessage function.

When you create a session you must specify one of several acknowledge modes for that session. If you specify MQ_CLIENT_ACKNOWLEDGE as the acknowledge mode for the session, you must explicitly call the MQAcknowledgeMessages function to acknowledge messages that you have received.

For more information about the signature and content of a call back function, see "Callback Type for Asynchronous Messaging".

When the callback function is called by the session delivery of a message, it gives you a handle to the delivered message. You can pass that handle to the functions described in "Processing a Message", in order to read message properties and information stored in the header and body of the message.

Processing a Message

When a message is delivered to you, you can examine the messages properties, type, headers, and body. The functions used to process a message are described in Table 3-9.

Table 3-9  Functions Used to Process Messages 

Function

Description

MQGetMessageHeaders

Gets message header properties.

MQGetMessageProperties

Gets user-defined message properties.

MQGetMessageType

Gets the message type: MQ_TEXT_MESSAGE or MQ_BYTES_MESSAGE

MQGetTextMessageText

Gets the body of an MQ_TEXT_MESSAGE message.

MQGetBytesMessageBytes

Gets the body of an MQ_BYTES_MESSAGE message.

MQGetMessageReplyTo

Gets the destination where replies to this message should be sent.

If you are interested in a message’s header information, you need to call the MQGetMessageHeaders function. If you need to read or check any user-defined properties, you need to call the MQGetMessageProperties function. Each of these functions passes back a properties handle. For information on how you can read property values, see "Getting Message Properties".

Before you can examine the message body, you can call the MQGetMessageType function to determine whether the message is a text or bytes message. You can then call the MQGetTextMessageText, or the MQGetBytesMessageBytes function to get the contents of the message.

Some message senders specify a reply destination for their message. Use the MQGetMessageReplyTo function to determine that destination.


Error Handling

Nearly all MQ C functions return an MQStatus result. You can use this return value to determine whether the function returned successfully and, if not, to determine the cause of the error.

Table 3-10 lists the functions you use to get error information.

Table 3-10  Functions Used in Handling Errors 

Function

Description

MQStatusIsError

Returns an MQ_TRUE if the specified MQStatus is an error.

MQGetStatusCode

Returns the error code for the specified MQStatus.

MQGetStatusString

Returns a descriptive string for the specified MQStatus.

MQGetErrorTrace

Returns the calling thread’s current error trace or NULL if no error trace is available.

    To Handle Errors in Your Code
  1. Call MQStatusIsError, passing it an MQStatus result for the function whose result you want to test.
  2. If the MQStatusIsError function, returns MQ_TRUE, call MQGetStatusCode or MQGetStatusString to identify the error.
  3. If the status code and string information is not sufficient to identify the cause of the error, you can get additional diagnostic information by calling MQGetErrorTrace to obtain the calling thread’s current error trace if this information is available.

Chapter 4, "Reference", lists common errors returned for each function. In addition to these errors, the following error codes may be returned by any MQ C function:

In addition, the MQ_TIMEOUT_EXPIRED can return from any MQ C function that communicates with the MQ broker if the connection MQ_ACK_TIMEOUT_PROPERTY is set to a non-zero value.


Memory Management

Table 3-11 lists the functions you use to free or deallocate memory allocated by the MQ-C client library on behalf of the user. Such deallocation is part of normal memory management and will prevent memory leaks.

The functions MQCloseConnection, MQCloseSession, MQCloseMessageProducer, and MQCloseMessageConsumer are used to free resources associated with connections, sessions, producers, and consumers.

Table 3-11  Functions Used to Free Memory 

Function

Description

MQFreeConnection

Frees memory allocated to the specified connection.

MQFreeDestination

Frees memory allocated to the specified destination.

MQFreeMessage

Frees memory allocated to the specified message.

MQFreeProperties

Frees memory allocated to the specified properties handle.

MQFreeString

Frees memory allocated to the specified MQString.

You should free a connection only after you have closed the connection with the MQCloseConnection function and after all of the application threads associated with this connection and its dependent sessions, producers, and consumers have returned.

You should not free a connection while an application thread is active in a library function associated with this connection or one of its dependent sessions, producers, consumers, and destinations.

Freeing a connection does not release resources held by a message associated with this connection. You must free memory allocated for this message by explicitly calling the MQFreeMessage function.

You should not free a properties handle if the properties handle passed to a function becomes invalid on its return. If you do, you will get an error.


Thread Management

This section addresses a number of thread management issues that you should be aware of in designing and programming an MQ C client.

MQ C Runtime Thread Model

The MQ C-API library creates the thread(s) needed to provide runtime support for an MQ C client. It uses NSPR (Netscape Portable Runtime) GLOBAL threads. NSPR GLOBAL threads are fully compatible with native threads on each supported platform. Table 3-12 shows the thread model that the NSPR GLOBAL threads map to on each platform. For more information on NSPR, please see

http://www.mozilla.org/projects/nspr/

Table 3-12  Thread Model for NSPR GLOBAL Threads

Platform

Thread Model

Solaris

pthreads

Linux

pthreads

Windows

Win32 threads (from Microsoft Visual C++ runtime library msvcrt)

Concurrent Use of Handles

Table 3-13 lists the handles (objects) used in a C client program and specifies which of these may be used concurrently and which can only be used by one logical thread at a time.

Table 3-13  Handles and Concurrency 

Handle

Supports Concurrent Use

MQDestinationHandle

YES

MQConnectionHandle

YES

MQSessionHandle

NO

MQProducerHandle

NO

MQConsumerHandle

NO

MQMessageHandle

NO

MQPropertiesHandle

NO

Single-Threaded Session Control

A session is a single-threaded context for producing and consuming messages. Multiple threads should not use the same session concurrently nor use the objects it creates concurrently. The only exception to this occurs during the orderly shutdown of the session or its connection when the client calls the MQCloseSession or the MQCloseConnection function.

The MQ C runtime library provides one thread to a session in MQ_SESSION_ASYNC_RECEIVE mode for asynchronous message delivery to its consumers. When the connection is started, all its sessions that have created asynchronous consumers are dedicated to the thread of control that delivers messages. Client code should not use such a session from another thread of control. The only exception to this is the use of MQ CLoseSession and MQCloseConnection.

Connection Exceptions

When a connection exception occurs, the MQ C library thread that is provided to the connection calls its MQConnectionExceptionListenerFunc callback if one exists. If an MQConnectionExceptionListenerFunc callback is used for multiple connections, it can potentially be called concurrently from different connection threads.

You should not call the MQCloseConnection function in an MQConnectionExceptionListenerFunc callback. Instead the callback function should notify another thread to call MQCloseConnection and return.


Logging

The MQ C-API library uses two environment variables to control execution-time logging:



Previous      Contents      Index      Next     


Copyright 2003 Sun Microsystems, Inc. All rights reserved.