Calls user-supplied functions to handle interrupts while waiting on a read from the server.
void dbsetinterrupt(dbproc, chkintr, hndlintr) DBPROCESS *dbproc; int (*chkintr)(); int (*hndlintr)();
A pointer to the DBPROCESS structure that provides the connection for a particular front-end/server process. It contains all the information that DB-Library uses to manage communications and data between the front end and server.
A pointer to the user function that DB-Library calls to check whether an interrupt is pending. DB-Library calls it periodically while waiting on a read from the server. DB-Library calls chkintr() with a single parameter—a pointer to the DBPROCESS from the dbsetinterrupt call.
chkintr() must return “TRUE” or “FALSE”.
A pointer to the user function that DB-Library calls if an interrupt is returned. DB-Library calls hndlintr() with a single parameter—a pointer to the DBPROCESS from the dbsetinterrupt call.
Table 2-27 lists the legal return values of hndlintr:
Return value |
To indicate |
---|---|
INT_EXIT |
Abort the program. (Note to UNIX programmers: DB-Library will not leave a core file. |
INT_CANCEL |
Abort the current command batch. Results are not flushed from the DBPROCESS connection. |
INT_CONTINUE |
Continue to wait for the server response. |
None.
DB-Library does non-blocking reads from the server. While waiting for a read from the server, it calls the chkintr() function to see if an interrupt is pending. If chkintr() returns “TRUE” and a handler has been installed as the hndlintr() for dbsetinterrupt, hndlintr() is called. dbsetinterrupt is provided so that the programmer can substitute alternative interrupt handling for the time that the host program is waiting on reads from the server.
Depending on the return value from hndlintr(), DB-Library performs one the following actions:
Sends an attention to the server, causing the server to discontinue processing (INT_CANCEL). For details, see “Canceling from the interrupt handler”.
Continues reading from the server (INT_CONTINUE).
Exits the program (INT_EXIT).
If hndlintr() returns INT_CANCEL, DB-Library sends an attention token to the server. This causes the server to discontinue command processing. The server may send additional results that have already been computed. When control returns to the mainline code, the mainline code should do one of the following:
Flush the results using dbcancel
Process the results normally
You cannot call dbcancel in your interrupt handler, because this will cause output from the server to DB-Library to become out of sync. The steps below describe a correct method to cancel from the interrupt handler.
Associate an int_canceled flag with the DBPROCESS structure. Use dbsetuserdata to install a pointer to the flag in the DBPROCESS, and dbgetuserdata to get the address of the flag.
Code hndlintr() to set the int_canceled flag to indicate whether or not it is returning INT_CANCEL.
In the mainline code, check the flag before each call to dbresults or dbnextrow. When the int_canceled flag indicates that hndlintr() has aborted the server command, the mainline code should call dbcancel and clear the flag.
Here are example chkintr() and hndlintr() routines:
The applications chkintr()
and hndlintr()
routines are callback functions and must be declared as CS_PUBLIC for
the Windows platform. For portability, callback handlers on other
platforms should be declared CS_PUBLIC as
well.
int CS_PUBLIC chkintr(dbproc)
DBPROCESS *dbproc;
{
/*
** This routine assumes that the application
** sets the global variable
** "OS_interrupt_happened" upon catching
** an interrupt using some operating system
** facility.
*/
if (OS_interrupt_happened)
{
/*
** Clear the interrupt flag, for
** future use.
*/
OS_interrupt_happened = FALSE;
return(TRUE);
}
else
return(FALSE);
}
int CS_PUBLIC hndlintr(dbproc)
DBPROCESS *dbproc;
{
char response[10];
DBBOOL *int_canceled;
/*
** We assume that a DBBOOL flag has been
** attached to dbproc with dbsetuserdata.
*/
int_canceled = (DBBOOL *) dbgetuserdata(dbproc);
if (int_canceled == (DBBOOL *)NULL)
{
printf(“Fatal Error: no int_cancel flag \
in the DBPROCESS\n”);
return(INT_EXIT);
}
*int_canceled = FALSE;
printf("\nAn interrupt has occurred. Do you \
want to:\n\n");
printf("\t1) Abort the program\n");
printf("\t2) Cancel the current query\n");
printf("\t3) Continue processing the current\
query’s results\n\n");
printf("Press 1, 2, or 3, followed by the \
return key: ");
gets(response);
switch(response[0])
{
case ’1’:
return(INT_EXIT);
break;
case ’2’:
*int_canceled = TRUE;
return(INT_CANCEL);
break;
case ’3’:
return(INT_CONTINUE);
break;
default:
printf("Response not understood. \
Aborting program.\n");
return(INT_EXIT);
break;
}
}
dbcancel, dbgetuserdata, dbsetuserdata, dbsetbusy, dbsetidle