CS_TIMEOUT specifies the length of time, in seconds, that Client-Library waits for a server response to a command.
The default timeout value is CS_NO_LIMIT, which represents an infinite timeout period. Negative and zero values are not allowed for CS_TIMEOUT.
ct_config is called to set the timeout value before or after a call to ct_connect creates an open connection. It takes effect for all open connections immediately upon being called.
The following code fragment sets a 60-second timeout limit:
CS_INT timeval;
timeval = 60;
if (ct_config(ctx, CS_SET, CS_TIMEOUT,
(CS_VOID *)&timeval,
CS_UNUSED, NULL)
!= CS_SUCCEED)
{
fprintf(stdout,“Can't config timeout. Exiting.“);
(void)ct_exit(ctx, CS_FORCE_EXIT);
(void)cs_ctx_drop(ctx);
exit(1);
}
Timeout errors occur in synchronous applications that have set either or both of the CS_TIMEOUT or CS_LOGIN_TIMEOUT properties to values other than CS_NO_LIMIT. CS_LOGIN_TIMEOUT sets the timeout period for reading the server’s response to a login attempt, while CS_TIMEOUT sets the timeout period for reading the results of a server command. The application receives the same Client-Library message for timeouts in both cases. (See “Login timeout” for a description of the CS_LOGIN_TIMEOUT property).
You can specify CS_TIMEOUT or CS_LOGIN_TIMEOUT values on on a per-connection basis with ct_con_props.
Applications that use inline error handling must set the CS_DIAG_TIMEOUT property to specify whether Client-Library should abort or retry when a timeout occurs. See “Diagnostic timeout fail” for more information.
Applications that handle Client-Library messages with a callback can identify the timeout error and either cancel the operation or retry for another timeout period. A client message callback has the following options for handling a timeout message:
Return CS_FAIL to cancel the operation and mark the connection as dead. This is the only way to abort a login attempt that has timed out.
(Non-login timeouts only.) Call ct_cancel(CS_CANCEL_ATTN) to cancel the command that is being processed, then return CS_SUCCEED.
Return CS_SUCCEED to retry for another timeout period.
A timeout error is identified by breaking the error number (identified by the number field of the CS_CLIENTMSG structure) into its four components and checking whether the error number matches the following characteristics:
Severity – CS_SV_RETRY_FAIL
Number – 63
Origin – 2
Layer – 1
An application breaks an error number into components with the CS_SEVERITY, CS_NUMBER, CS_ORIGIN, and CS_LAYER macros. See “Client-Library message numbers” for a description of these macros. An example of testing for timeout errors is provided below.
The callback checks the value of the CS_LOGIN_STATUS connection property to see whether the timeout is happening during connection establishment or during command processing. If the property is CS_TRUE, the connection is already established and the server has timed out during command processing.
The following code fragment defines a client message callback that handles timeout errors:
/*
** ERROR_SNOL(error_numb, severity, number, origin, layer)
**
** Error comparison for Client-Library or CS-Library errors.
** Breaks down a message number and compares it to the given
** constants for severity, number, origin, and layer.
** Returns non-zero if the error number matches the 4
** constants.
*/
#define ERROR_SNOL(e, s, n, o, l) \
( (CS_SEVERITY(e) == s) && (CS_NUMBER(e) == n) \
&& (CS_ORIGIN(e) == o) && (CS_LAYER(e) == l ) )
CS_RETCODE client_msg_handler(cp, conn, emsgp)
CS_CONTEXT *cp;
CS_CONNECTION *conn;
CS_CLIENTMSG *emsgp;
{
CS_RETCODE ret;
CS_INT status;
... code to print message details and handle any other
errors besides timeout ...
/*
** Is this a timeout error?
*/
if (ERROR_SNOL(emsgp->msgnumber, CS_SV_RETRY_FAIL, 63, 2, 1))
{
/*
** Read from server timed out. Timeouts happen on synchronous
** connections only, and you must have set one or both of the
** following context properties to see them:
** CS_TIMEOUT for results timeouts
** CS_LOGIN_TIMEOUT for login-attempt timeouts
**
** If we return CS_FAIL, the connection is marked as dead and
** unrecoverable. If we return CS_SUCCEED, the timeout
** continues for another quantum.
**
** We kill the connection for login timeouts, and send a
** cancel for results timeouts. We determine which case we
** have through the CS_LOGIN_STATUS property.
*/
status = 0;
if (ct_con_props(conn, CS_GET, CS_LOGIN_STATUS,
(CS_VOID *)&status,
CS_UNUSED, NULL) != CS_SUCCEED)
{
fprintf(stdout, "ct_con_props() failed in error handler.");
return CS_FAIL;
}
if (status)
{
/* Results timeout */
fprintf(stdout, "Issuing a cancel on the query...\n");
(CS_VOID)ct_cancel(conn, (CS_COMMAND *)NULL,
CS_CANCEL_ATTN);
}
else
{
/* Login timeout */
fprintf(stdout, "Aborting connection attempt...\n");
return CS_FAIL;
}
}
return (CS_SUCCEED);
}