Continuous Processing with isc que events()

From InterBase
Jump to: navigation, search

isc_que_events() is called to request asynchronous notification of events listed in an event buffer passed as an argument. Upon completion of the call, but before any events are posted, control is returned to the calling application so that it can continue processing.

When a requested event is posted, InterBase calls an asynchronous trap (AST) function, also passed as a parameter to isc_que_events(), to handle the posting. The AST is a function or subroutine in the calling application, the sole purpose of which is to process the event posting for the application.

The syntax for isc_que_events() is:

ISC_STATUS isc_que_events(ISC_STATUS *status_vector,
isc_db_handle *db_handle,
ISC_LONG *event_id,
short length,
char *event_buffer,
isc_callback event_function,
void *event_function_arg);

event_id is a long pointer that is used as a handle in subsequent calls to isc_cancel_events() to terminate event notification. It need not be initialized when passed. The length parameter is the size of event_buffer, which contains the current count of events to be waited upon. event_function is a pointer to the AST function that InterBase should call when an event of interest is posted. It is up to the AST function to notify the application that it has been called, perhaps by setting a global flag of some kind. event_function_arg is a pointer to the first parameter to pass to the AST.

For a complete example of a call to isc_que_events() and a call to an AST, see A Complete isc_que_events() Example.

Creating an AST

The event function, event_function(), should be written to take three arguments:

  1. The event_function_arg specified in the call to isc_que_events(). This is usually a pointer to the event parameter buffer that should be filled in with updated event counts.
  2. The length of the following events_list buffer.
  3. A pointer to the events_list buffer, a temporary event parameter buffer just like that passed to isc_que_events(), except for having updated event counts.

A result buffer is not automatically updated by the event occurrence; it is up to the event_function to copy the temporary events_list buffer to the more permanent buffer that the application utilizes.

event_function also needs to let the application know that it has been called, for example, by setting a global flag.

A sample event_function appears in the following example:

isc_callback event_function(char *result, short length, char *updated)
{
/* Set the global event flag. */
event_flag++
/* Copy the temporary updated buffer to the result buffer. */
while (length--)
  • result++ = *updated++;
return(0);
};

A Complete isc_que_events() Example

The following program fragment illustrates calling isc_que_events() to wait asynchronously for event occurrences. Within a loop, it performs other processing, and checks the event flag (presumably set by the specified event function) to determine when an event has been posted. If one has, the program resets the event flag, calls isc_event_counts() to determine which events have been posted since the last call to isc_que_events(), and calls isc_que_events() to initiate another asynchronous wait.

#include <ibase.h>
#define number_of_stocks 3;
#define MAX_LOOP 10
char *event_names[] = {"DEC", "HP", "SUN"};
char *event_buffer, *result_buffer;
ISC_STATUS status_vector[20];
short length;
ISC_LONG event_id;
int i, counter;
int event_flag = 0;
length = (short)isc_event_block(&event_buffer, &result_buffer,
number_of_stocks, "DEC", "HP", "SUN");
isc_que_events(status_vector,
&database_handle, /* Set in previous isc_attach_database(). */
&event_id,
length, /* Returned from isc_event_block(). */
event_buffer,
(isc_callback)event_function,
result_buffer);
if (status_vector[0] == 1 && status_vector[1]) {
isc_print_status(status_vector); /* Display error message. */
return(1);
};
counter = 0;
while (counter < MAX_LOOP) {
counter++;
if (!event_flag) {
/* Do whatever other processing you want. */
}
else {
event_flag = 0;
isc_event_counts(status_vector, length, event_buffer, result_buffer);
if (status_vector[0] == 1 && status_vector[1]) {
isc_print_status(status_vector); /*Display error message.*/
return(1);
};
for (i=0; i<number_of_stocks; i++)
if (status_vector[i]) {
/* The event has been posted. Do whatever is appropriate,
* such as initiating a buy or sell order. Note: event_names[i]
* tells the name of the event corresponding to status_vector[i]. */
}
isc_que_events(status_vector, &database_handle, &event_id, length,
event_buffer, (isc_callback)event_function, result_buffer);
if (status_vector[0] == 1 && status_vector[1]) {
isc_print_status(status_vector); /*Display error message.*/
return(1);
}
} /* End of else. */
} /* End of while. */
/* Let InterBase know you no longer want to wait asynchronously. */
isc_cancel_events(status_vector, &database_handle, &event_id);
if (status_vector[0] == 1 && status_vector[1]) {
isc_print_status(status_vector); /* Display error message. */
return(1);

}

Advance to Next Topic