Brief Description

This change is applicable to Classic architecture only. Engine Performance improvement - reduce setting of FPE handler.

Purpose

During GBAK performance testing, it was discovered that approximately 5% of time was spent setting/resetting the InterBase Floating Point Exception handler. By changing when the FPE is reset we free up virtually all this time, with minimal customer impact.

Customers are only impacted if they use the Shared or backend libraries, Have their own FPE handler, and reset their FPE handler while being attached to a database.

Feature Description

Functional Changes

Prior to this change, InterBase managed FPE handlers as follows:
On entry to each API call, we would fetch the current (client's) FPE handler setting, and set the FPE signal to go to our handler. On exit from each API call we would reset SIGFPE to the client's handler. The InterBase FPE handler (isc_ipc.c:overflow_handler) simply ignored an FPE. The point of this methodology was to use the InterBase FPE handler to ignore any FPE's that occur while executing within the engine. FPE's that occur when outside the engine would follow whatever protocol the client had setup. (And, if the customer had no FPE handler, would result in a client core-drop).

In the new methodology, the following is used:
Each API call increments/decrements a counter to indicate when we're in the engine. For each ATTACHMENT (database or service) we setup the isc FPE handler. The isc handler checks the API counter to decide if the FPE occurred while within engine code. If so, we ignore the FPE. Otherwise, we chain to the client's FPE handler, if it exists.when there are no active ATTACHMENT's, we remove the isc FPE handler.

Notes:
FPE's are rare, in general. Programs having FPE handlers are even rarer, in general. It's unlikely that customer programs care about having FPE handlers Support generally recommends customers doing signal handling of any form use PIPE.

Issues

Migration

Applications using Remote or PIPE show no difference.
Applications never having an instance of an FPE show no difference.
Applications which never setup their own FPE handler differ as follows: An FPE occurring in CLIENT code will no longer core drop but will silently have the FPE ignored, if the FPE occurs after the first database attach.
Applications which setup their own FPE handlers differ as follows: If the FPE handler is setup before the first attach, and never changed, no difference is shown. If the FPE handler is setup or changed after the first attach, the client's handler will be called instead of the ISC handler for FPE's that occur within the engine. (Clients can evade this change by calling private API isc_reset_fpe() to inform the engine when changes in client FPE handler have been made)
It is possible for an FPE to be "delayed" until an engine operation completes. This would be significant for applications that use SIGFPE for their own purposes (e.g.: not to indicate a Floating Point Exception). This is similar to how the engine postpones processing of SIGUSR1 and SIGUSR2 under some instances. While the client's FPE handler will be invoked, it will be via the isc generic signal handler routine (isc_ipc.c:signal_handler).
I can imagine difficulties if a client tries to load/unload isc libraries dynamically. These would be resolved by the customer resetting the signal handler when the isc libraries are unloaded.