ATMI C Function Reference
|
|
tpgetrply()—Routine for getting a reply from a previous request.
#include <atmi.h>
int tpgetrply(int *cd, char **data, long *len, long flags)
tpgetrply() returns a reply from a previously sent request. This function's first argument, cd, points to a call descriptor returned by tpacall(). By default, the function waits until the reply matching *cd arrives or a timeout occurs.
data must be the address of a pointer to a buffer previously allocated by tpalloc() and len should point to a long that tpgetrply() 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 data. FML and FML32 buffers often assume a minimum size of 4096 bytes; if the reply is larger than 4096, the size of the buffer is increased to a size large enough to accommodate the data being returned. As of release 6.4, the default allocation for buffers is 1024 bytes. Also, historical information is maintained on recently used buffers, allowing a buffer of optimal size to be reused as a return buffer.
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 send. 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 tpgetrply() was issued with *len. See the Introduction to the C Language Application-to-Transaction Monitor Interface for more information about buffer management.
If *len is 0, then the reply 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.
Within any particular context of a multithreaded program:
tpgetrply(TPGETANY) and tpgetrply() for a specific handle cannot be issued concurrently.tpgetrply(TPGETANY) cannot be issued concurrently.Any tpgetrply() call that would, if issued, cause a violation of either of these restrictions, returns -1 and sets tperrno to TPEPROTO.
tpgetrply() for different handles.tpgetrply(TPGETANY) in a single context concurrently with a call to tpgetrply(), with or without TPGETANY, in a different context.The following is a list of valid flags:
This flag signifies that tpgetrply() should ignore the descriptor pointed to by cd, return any reply available and set cd to point to the call descriptor for the reply returned. If no replies exist, tpgetrply() by default will wait for one to arrive.
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.
tpgetrply() does not wait for the reply to arrive. If the reply is available, then tpgetrply() gets the reply and returns. When this flag is not specified and a reply is not available, the caller blocks until the reply arrives or a timeout occurs (either transaction or blocking timeout).
This flag signifies that the caller is willing to block indefinitely for its reply and wants to be immune to blocking timeouts. Transaction timeouts may still occur.
Except as noted below, *cd is no longer valid after its reply is received.
In a multithreaded application, a thread in the TPINVALIDCONTEXT state is not allowed to issue a call to tpgetrply().
Upon successful return from tpgetrply() or upon return where tperrno is set to TPESVCFAIL, tpurcode() contains an application defined value that was sent as part of tpreturn().
Upon failure, tpgetrply() returns -1 and sets tperrno to indicate the error condition.
Upon failure, tpgetrply() sets tperrno as indicated below. Note that if TPGETANY is not set, then *cd is invalidated unless otherwise stated. If TPGETANY is set, then cd points to the descriptor for the reply on which the failure occurred; if an error occurred before a reply could be retrieved, then cd points to 0. Also, the failure does not affect the caller's transaction, if one exists, unless otherwise stated. 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.
Invalid arguments were given (for example, cd, data, *data or len is NULL or flags are invalid). If cd is non-NULL, then it is still valid after this error and the reply remains outstanding.
Either the type and subtype of the reply 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 reply sent by the service. Regardless, neither *data, its contents nor *len are changed. If the reply was to be received on behalf of the caller's current transaction, then the transaction is marked abort-only since the reply is discarded.
This error code indicates that either a timeout has occurred or tpgetrply() 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, its contents, or *len. *cd remains valid unless the caller is in transaction mode (and TPGETANY has not been set).
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 a service 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.
The service routine sending the caller's reply called tpreturn() with TPFAIL. This is an application-level failure. The contents of the service's reply, if one was sent, is available in the buffer pointed to by *data. If the service request was made on behalf of the caller's transaction, then the transaction is marked abort-only. Note that regardless of whether the transaction has timed out, the only valid communications before the transaction is aborted are calls to tpacall() with TPNOREPLY, TPNOTRAN, and TPNOBLOCK set.
A service routine encountered an error either in tpreturn() or tpforward() (for example, bad arguments were passed). No reply data is returned when this error occurs (that is, neither *data, its contents nor *len are changed). If the service request was made on behalf of the caller's transaction, then the transaction is marked abort-only. Note that regardless of whether the transaction has timed out, the only valid communications before the transaction is aborted are calls to tpacall() with TPNOREPLY, TPNOTRAN, and TPNOBLOCK set. If either SVCTIMEOUT in the UBBCONFIG file or TA_SVCTIMEOUT in the TM_MIB is non-zero, TPESVCERR is returned when a service timeout occurs.
tpacall(3c), tpalloc(3c), tpcancel(3c), tperrordetail(3c), tprealloc(3c), tpreturn(3c), tpstrerrordetail(3c), tptypes(3c)
|
|
|