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)