PURPOSE

tpdequeue - routine to dequeue a message from a queue

SYNOPSIS

#include <atmi.h>
int tpdequeue(char *qspace, char *qname, TPQCTL *ctl, char **data, long *len,
  long flags)

DESCRIPTION

tpdequeue() dequeues a message for processing from the queue named by qname in the qspace queue space.

By default, the message at the top of the queue is dequeued. The default order of messages on the queue is defined when the queue is created. The application can request a particular message for dequeuing by specifying its message identifier using the ctl parameter. ctl flags can also be used to indicate that the application wants to wait for a message, in the case where a message is not currently available. See the section below describing this parameter.

data is the address of a pointer to the buffer into which a message is read, and len points to the length of that message. *data must point to a buffer originally allocated by tpalloc(3c). To determine whether a message buffer changed in size, compare its (total) size before tpdequeue() was issued with *len. Note that *data may change for reasons other than the buffer's size increased. If *len is 0 upon return, then the message dequeued has no data portion and neither *data nor the buffer it points to were modified. It is an error for *data or len to be NULL.

The message is dequeued in transaction mode if the caller is in transaction mode and the TPNOTRAN flag is not set. This has the effect that if tpdequeue() returns successfully and the caller's transaction is committed successfully, then the message is deleted from the queue. If the caller's transaction is rolled back either explicitly or as the result of a transaction timeout or some communication error, then the message will be left on the queue (that is, the deletion of the message from the queue is also rolled back). This can be exploited to "peek" at a message on the queue, rolling back the transaction to leave the message on the queue (note that this cannot be done in TPNOTRAN mode as described below). It is not possible to enqueue and dequeue the same message within the same transaction.

The message is not dequeued in transaction mode if either the caller is not in transaction mode, or the TPNOTRAN flag is set. The message is dequeued in a separate transaction. If a communication error or a timeout occurs (either transaction or blocking timeout), the application will not know whether or not the message was successfully dequeued and the message may be lost.

Following is a list of valid flags.

TPNOTRAN
If the caller is in transaction mode and this flag is set, then the message is not dequeued within the same transaction as the caller. A caller in transaction mode that sets this flag is still subject to the transaction timeout (and no other) when dequeuing the message. If message dequeuing fails, the caller's transaction is not affected.
TPNOBLOCK
The message is not dequeued if a blocking condition exists (for example, the internal buffers into which the message is transferred are full). If such a condition occurs, the call fails and tperrno is set to TPEBLOCK. When TPNOBLOCK is not specified and a blocking condition exists, the caller blocks until the condition subsides or a timeout occurs (either transaction or blocking timeout). This blocking condition does not include blocking on the queue itself if the TPQWAIT option is specified.
TPNOTIME
This flag signifies that the caller is willing to block indefinitely and wants to be immune to blocking timeouts. Transaction timeouts may still occur.
TPNOCHANGE
When this flag is set, the type of the buffer pointed to by *data is not allowed to change. By default, if a buffer is received that differs in type from the buffer pointed to by *data, then *data's buffer type changes to the received buffer's type so long as the receiver recognizes the incoming buffer type. That is, the type and sub-type of the dequeued message must match the type and sub-type of the buffer pointed to by *data.
TPSIGRSTRT
If a signal interrupts any underlying system calls, then the interrupted system call is re-issued. When TPSIGRSTRT is not specified and a signal interrupts a system call, then tpdequeue() fails and tperrno is set to TPGOTSIG.

If tpdequeue() returns successfully, the application can retrieve additional information about the message using ctl data structure. The information may include the message identifier for the dequeued message, a correlation identifier that should accompany any reply or failure message so that the originator can correlate the message with the original request, the name of a reply queue if a reply is desired, and the name of the failure queue on which the application can queue information regarding failure to dequeue the message. This is described below.

Control Parameter

The TPQCTL structure is used by the application program to pass and retrieve parameters associated with dequeuing the message. The flags element of TPQCTL is used to indicate what other elements in the structure are valid.

On input to tpdequeue(), the following elements may be set in the TPQCTL structure:


long flags;            /* indicates which of the values
                        * are set */
char msgid[32];        /* id of message to dequeue */
char corrid[32];       /* correlation identifier of
                        * message to dequeue */

Following is a list of valid bits for the flags parameter controlling input information for tpdequeue().

TPNOFLAGS
No flags are set. No information is taken from the control structure.
TPQGETBYMSGID
If set, it requests that the message identified by ctl->msgid be dequeued. The message identifier would be one that was returned by a prior call to tpenqueue(3c). Note that the message identifier is not valid if the message has moved from one queue to another; in this case, use the correlation identifier. This option cannot be used with the TPQWAIT option.
TPQGETBYCORRID
If set, it requests that the message with the correlation identifier specified by ctl->corrid be dequeued. The correlation identifier would be one that the application specified when enqueuing the message with tpenqueue(). This option cannot be used with the TPQWAIT option.
TPQWAIT
If set, it indicates that an error should not be returned if the queue is empty. Instead, the process should block until a message is available.

On output from tpdequeue(), the following elements may be set in the TPQCTL structure:


long flags;            /* indicates which of the values
                        * should be set */
long priority;         /* enqueue priority */
char msgid[32];        /* id of message dequeued */
char corrid[32];       /* correlation identifier used to
                        * identify the message */
char replyqueue[16];   /* queue name for reply */
char failurequeue[16]; /* queue name for failure */
long diagnostic;       /* reason for failure */
long appkey;           /* application authentication client
                        * key */
long urcode;           /* user-return code */
CLIENTID cltid;        /* client identifier for originating
                        * client */

Following is a list of valid bits for the flags parameter controlling output information from tpdequeue(). If the flag bit is turned on when tpdequeue() is called, then the associated element in the structure is populated if available and the bit remains set. If the value is not available, the flag bit will be turned off after tpdequeue() completes.

TPQPRIORITY
If set and the value is available, the priority at which the message was queued is stored in ctl->priority. The priority is in the range 1 to 100, inclusive, and the higher the number, the higher the priority (that is, a message with a higher number is dequeued before a message with a lower number).
TPQMSGID
If set and the call to tpdequeue() was successful, the message identifier will be stored in ctl->msgid.
TPQCORRID
If set and the call to tpdequeue() was successful and the message was queued with a correlation identifier, the value will be stored in ctl->corrid. Any reply to a queue must have this correlation identifier.
TPQREPLYQ
If set and the message is associated with a reply queue, the value will be stored in ctl->replyqueue. Any reply to the message should go to the named reply queue within the same queue space as the request message.
TPQFAILUREQ
If set and the message is associated with a failure queue, the value will be stored in ctl->failurequeue. Any failure message should go to the named failure queue within the same queue space as the request message.

If the call to tpdequeue() failed and tperrno is set to TPEDIAGNOSTIC, a value indicating the reason for failure is returned in ctl->diagnostic. The possible values are defined below in the DIAGNOSTICS section.

Additionally on output, ctl->appkey is set to application authentication key, ctl->cltid is set to the identifier for the client originating the request, and ctl->urcode is set to the user-return code value that was set when the message was enqueued.

If the ctl parameter is NULL, the input flags are considered to be TPNOFLAGS and no output information is made available to the application program.

RETURN VALUES

This function returns -1 on error and sets tperrno to indicate the error condition.

ERRORS

Under the following conditions, tpdequeue() fails and sets tperrno to one of the following (unless otherwise noted, failure does not affect the caller's transaction, if one exists):

[TPEINVAL]
Invalid arguments were given (for example, qname is NULL, data does not point to space allocated with tpalloc(3c) or flags are invalid).
[TPENOENT]
Cannot access the qspace because it is not available (the associated TMQUEUE(5) server is not available) or the name begins with "..".
[TPEOTYPE]
Either the type and sub-type of the dequeued message are not known to the caller; or, TPNOCHANGE was set in flags and the type and sub-type of *data do not match the type and sub-type of the dequeued message. Regardless, neither *data, its contents nor *len are changed. When this error occurs, the transaction is marked abort-only and the message will remain on the queue.
[TPETIME]
A timeout occurred. If the caller is in transaction mode, then a transaction timeout occurred and the transaction is to be aborted; otherwise, a blocking timeout occurred and neither TPNOBLOCK nor TPNOTIME were specified. If a transaction timeout occurred, any attempts to dequeue new messages will fail with TPETIME until the transaction has been aborted.
[TPEBLOCK]
A blocking condition exists and TPNOBLOCK was specified.
[TPGOTSIG]
A signal was received and TPSIGRSTRT was not specified.
[TPEPROTO]
tpdequeue() was called in an improper context. There is no effect on the queue or the transaction.
[TPESYSTEM]
A System /T error has occurred. The exact nature of the error is written to a log file. There is no effect on the queue.
[TPEOS]
An operating system error has occurred. There is no effect on the queue.
[TPEDIAGNOSTIC]
Dequeuing a message from the specified queue failed. The reason for failure can be determined by the diagnostic value returned via ctl structure.

DIAGNOSTIC

The following diagnostic values are returned during the dequeuing of a message.

[QMEINVAL]
An invalid flag value was specified.
[QMEBADRMID]
An invalid resource manager identifier was specified.
[QMENOTOPEN]
The resource manager is not currently open.
[QMETRAN]
The call was made with the TPNOTRAN flag and an error occurred trying to start a transaction in which to dequeue the message.
[QMEBADMSGID]
An invalid message identifier was specified for dequeuing.
[QMEINUSE]
When dequeuing a message by correlation or message identifier, the specified message is in-use by another transaction. Otherwise, all messages currently on the queue are in-use by other transactions.
[QMESYSTEM]
A system error has occurred. The exact nature of the error is written to a log file.
[QMEOS]
An operating system error has occurred.
[QMEABORTED]
The operation was aborted. When executed within a global transaction, the global transaction has been marked rollback-only. Otherwise, the queue manager aborted the operation.
[QMEPROTO]
A dequeue was done when the transaction state was not active.
[QMEBADQUEUE]
An invalid or deleted queue name was specified.
[QMENOMSG]
No message was available for dequeuing.

SEE ALSO

tpalloc(3c),
tpenqueue(3c),
TMQUEUE(5)