ATMI C Function Reference
tprecv()
—Routine for receiving a message in a conversational connection.
#include <atmi.h>
int tprecv(int cd, char **data, long *len, long flags, long \
*revent)
tprecv()
is used to receive data sent across an open connection from another program. tprecv()
's first argument, cd
, specifies on which open connection to receive data. cd
is a descriptor returned from either tpconnect()
or the TPSVCINFO
parameter to the service. The second argument, data
, is the address of a pointer to a buffer previously allocated by tpalloc()
.
data
must be the address of a pointer to a buffer previously allocated by tpalloc()
and len
should point to a long that tprecv()
sets to the amount of data successfully received. Upon successful return, *data
points to a buffer containing the reply and *len
contains the size of the buffer. FML
and FML32
buffers often assume a minimum size of 4096 bytes; if the reply is larger than 4096 bytes, the size of the buffer is increased to a size large enough to accommodate the data being returned.
Buffers on the sending side that may be only partially filled (for example, FML or STRING buffers) will have only the amount that is used sent. The system may then enlarge the received data size by some arbitrary amount. This means that the receiver may receive a buffer that is smaller than what was originally allocated by the sender, yet larger than the data that was sent.
The receive buffer may grow, or it may shrink, and its address almost invariably changes, as the system swaps buffers around internally. To determine whether (and how much) a reply buffer changed in size, compare its total size before tprecv()
was issued with *len
. See Introduction to the C Language Application-to-Transaction Monitor Interface for more information about buffer management.
If *len
is 0, then no data was received and neither *data
nor the buffer it points to were modified. It is an error for data
, *data
or len
to be NULL.
tprecv()
can be issued only by the program that does not have control of the connection.
The following is a list of valid flags
:
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. When this flag is set, the type of the buffer pointed to by *data
is not allowed to change. That is, the type and subtype of the received buffer must match the type and subtype of the buffer pointed to by *data
.
tprecv()
does not wait for data to arrive. If data is already available to receive, then tprecv()
gets the data and returns. When this flag is not specified and no data is available to receive, the caller blocks until data arrives.
This flag signifies that the caller is willing to block indefinitely and wants to be immune to blocking timeouts. Transaction timeouts will still affect the program.
If an event exists for the descriptor, cd
, then tprecv()
will return setting tperrno
to TPEEVENT
. The event type is returned in revent
. Data can be received along with the TPEV_SVCSUCC
, TPEV_SVCFAIL
, and TPEV_SENDONLY
events. Valid events for tprecv()
are as follows:
Received by the subordinate of a conversation, this event indicates that the originator of the conversation has either issued an immediate disconnect on the connection via tpdiscon()
, or it issued tpreturn()
, tpcommit()
or tpabort()
with the connection still open. This event is also returned to the originator or subordinate when a connection is broken due to a communications error (for example, a server, machine, or network failure). Because this is an immediate disconnection notification (that is, abortive rather than orderly), data in transit may be lost. If the two programs were participating in the same transaction, then the transaction is marked abort-only. The descriptor used for the connection is no longer valid.
The program on the other end of the connection has relinquished control of the connection. The recipient of this event is allowed to send data but cannot receive any data until it relinquishes control.
Received by the originator of a conversation, this event indicates that the subordinate of the conversation has issued tpreturn()
. tpreturn()
encountered an error that precluded the service from returning successfully. For example, bad arguments may have been passed to tpreturn()
or tpreturn()
may have been called while the service had open connections to other subordinates. Due to the nature of this event, any application defined data or return code are not available. The connection has been torn down and is no longer a valid descriptor. If this event occurred as part of the cd
recipient's transaction, then the transaction is marked abort-only.
Received by the originator of a conversation, this event indicates that the subordinate service on the other end of the conversation has finished unsuccessfully as defined by the application (that is, it called tpreturn()
with TPFAIL
or TPEXIT
). If the subordinate service was in control of this connection when tpreturn()
was called, then it can pass an application defined return value and a typed buffer back to the originator of the connection. As part of ending the service routine, the server has torn down the connection. Thus, cd
is no longer a valid descriptor. If this event occurred as part of the recipient's transaction, then the transaction is marked abort-only.
Received by the originator of a conversation, this event indicates that the subordinate service on the other end of the conversation has finished successfully as defined by the application (that is, it called tpreturn()
with TPSUCCESS
). As part of ending the service routine, the server has torn down the connection. Thus, cd
is no longer a valid descriptor. If the recipient is in transaction mode, then it can either commit (if it is also the initiator) or abort the transaction causing the work done by the server (if also in transaction mode) to either commit or abort.
In a multithreaded application, a thread in the TPINVALIDCONTEXT
state is not allowed to issue a call to tprecv()
.
Upon return from tprecv()
where revent
is set to either TPEV_SVCSUCC
or TPEV_SVCFAIL
, the tpurcode
global contains an application defined value that was sent as part of tpreturn()
.
Upon failure, tprecv()
returns -1 and sets tperrno
to indicate the error condition. If a call fails with a particular tperrno
value, a subsequent call to tperrordetail()
, with no intermediate ATMI calls, may provide more detailed information about the generated error. Refer to the tperrordetail(3c)
reference page for more information.
Upon failure, tprecv()
sets tperrno
to one of the following values:
Invalid arguments were given (for example, data is not the address of a pointer to a buffer allocated by tpalloc()
or flags
are invalid).
Either the type and subtype of the incoming buffer are not known to the caller, or TPNOCHANGE
was set in flags
and the type and subtype of *data
do not match the type and subtype of the incoming buffer. Regardless, neither *data
, its contents nor *len
are changed. If the conversation is part of the caller's current transaction, then the transaction is marked abort-only because the incoming buffer is discarded.
This error code indicates that either a timeout has occurred or tprecv()
has been attempted, in spite of the fact that the current transaction is already marked rollback only.
If the caller is in transaction mode, then either the transaction is already rollback only or a transaction timeout has occurred. The transaction is marked abort-only. If the caller is not in transaction mode, a blocking timeout has occurred. (A blocking timeout cannot occur if TPNOBLOCK
and/or TPNOTIME
is specified.) In either case, no changes are made to *data
or its contents.
If a transaction timeout has occurred, then, with one exception, any attempts to send new requests or receive outstanding replies will fail with TPETIME
until the transaction has been aborted. The exception is a request that does not block, expects no reply, and is not sent on behalf of the caller's transaction (that is, tpacall()
with TPNOTRAN
, TPNOBLOCK
, and TPNOREPLY
set).
When an ATMI call fails inside a transaction, the transaction is put into the TX_ROLLBACK_ONLY
state. This state is treated, for most purposes, as though it were equivalent to a timeout. All further ATMI calls for this transaction (with the exception of those issued in the circumstances described in the previous paragraph) will fail with TPETIME
.
An event occurred and its type is available in revent. There is a relationship between the [TPETIME
] and the [TPEEVENT
] return codes. While in transaction mode, if the receiving side of a conversation is blocked on tprecv
and the sending side calls tpabort()
, then the receiving side gets a return code of [TPEVENT
] with an event of TPEV_DISCONIMM
. If, however, the sending side calls tpabort()
before the receiving side calls tprecv()
, then the transaction may have already been removed from the GTT, which causes tprecv()
to fail with the [TPETIME
] code.
tprecv()
was called in an improper context (for example, the connection was established such that the calling program can only send data).
A server can pass an application defined return value and typed buffer when calling tpreturn()
. The return value is available in the global variable tpurcode
and the buffer is available in data
.
tpalloc(3c)
, tpconnect(3c)
, tpdiscon(3c)
, tperrordetail(3c)
, tpsend(3c)
, tpservice(3c)
, tpstrerrordetail(3c)