49 |
Asc_SignHandlerPop(SIGFPE,Asc_SignalTrap); |
Asc_SignHandlerPop(SIGFPE,Asc_SignalTrap); |
50 |
Asc_SignalDestroy(); |
Asc_SignalDestroy(); |
51 |
</pre> |
</pre> |
52 |
* This example uses the built-in signal handler Asc_SignalTrap() |
|
53 |
* and the global <code>jmp_buf</code> g_fpe_env. After initializing |
This example uses the built-in signal handler Asc_SignalTrap() |
54 |
* the signal manager and registering the handler, <code>setjmp</code> |
and the global <code>jmp_buf</code> g_fpe_env. After initializing |
55 |
* is used to select normal and exception paths. The <code>setjmp</code> |
the signal manager and registering the handler, <code>setjmp</code> |
56 |
* returns 0 when initially called and the sqrt(x) is calculated. If |
is used to select normal and exception paths. The <code>setjmp</code> |
57 |
* x is negative, a SIGFPE exception occurs and the handler is called. It |
returns 0 when initially called and the sqrt(x) is calculated. If |
58 |
* uses <code>lngjmp</code> and returns to the if statement, and now |
x is negative, a SIGFPE exception occurs and the handler is called. It |
59 |
* <setjmp> returns non-zero and the <code>else</code> clause is executed. |
uses <code>lngjmp</code> and returns to the if statement, and now |
60 |
* Finally, the handler is removed and the signal manager cleaned up.<br><br> |
'setjmp' returns non-zero and the <code>else</code> clause is executed. |
61 |
* |
Finally, the handler is removed and the signal manager cleaned up.<br><br> |
62 |
* The stack mechanism also allows nested handlers to be registered. It is |
|
63 |
* important to note that nested handlers for the same signal type cannot |
The stack mechanism also allows nested handlers to be registered. It is |
64 |
* both use Asc_SignalTrap() as the handler. This is because different |
important to note that nested handlers for the same signal type cannot |
65 |
* <code>jmp_buf</code> variables must be used and Asc_SignalTrap() uses |
both use Asc_SignalTrap() as the handler. This is because different |
66 |
* the same global <code>jmp_buf</code> each time. However, you can use |
<code>jmp_buf</code> variables must be used and Asc_SignalTrap() uses |
67 |
* custome <code>jmp_buf</code>'s and handlers: |
the same global <code>jmp_buf</code> each time. However, you can use |
68 |
* <pre> |
custome <code>jmp_buf</code>'s and handlers: |
69 |
* Asc_SignalInit(); |
|
70 |
* Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap); |
<pre> |
71 |
* if (setjmp(g_fpe_env) == 0) { |
Asc_SignalInit(); |
72 |
* y = sqrt(x); |
Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap); |
73 |
* Asc_SignalHandlerPush(SIGFPE, my_handler); |
if (setjmp(g_fpe_env) == 0) { |
74 |
* if (setjmp(my_jmp_buf) == 0) { |
y = sqrt(x); |
75 |
* y = z/x; |
Asc_SignalHandlerPush(SIGFPE, my_handler); |
76 |
* } else { |
if (setjmp(my_jmp_buf) == 0) { |
77 |
* Asc_Panic(1, NULL, "Div by zero error."); |
y = z/x; |
78 |
* } |
} else { |
79 |
* Asc_SignHandlerPop(SIGFPE, my_handler); |
Asc_Panic(1, NULL, "Div by zero error."); |
80 |
* } else { |
} |
81 |
* y = sqrt(-x); |
Asc_SignHandlerPop(SIGFPE, my_handler); |
82 |
* } |
} else { |
83 |
* Asc_SignHandlerPop(SIGFPE,Asc_SignalTrap); |
y = sqrt(-x); |
84 |
* Asc_SignalDestroy(); |
} |
85 |
* </pre> |
Asc_SignHandlerPop(SIGFPE,Asc_SignalTrap); |
86 |
* Here, exceptions in the sqrt(x) calculation are handled by the standard |
Asc_SignalDestroy(); |
87 |
* Asc_SignalTrap(), while the division is handled by my_handler.<br><br> |
</pre> |
88 |
* |
|
89 |
* Avoid mixing use of the signal manager with direct calls to signal(). |
Here, exceptions in the sqrt(x) calculation are handled by the standard |
90 |
* Once Asc_SignalInit() has been called, use of signal() directly is likely |
Asc_SignalTrap(), while the division is handled by my_handler.<br><br> |
91 |
* to be lost or to corrupt the managed handlers.<br><br> |
|
92 |
* |
Avoid mixing use of the signal manager with direct calls to signal(). |
93 |
* Another warning: setjmp is expensive if called inside a fast loop. |
Once Asc_SignalInit() has been called, use of signal() directly is likely |
94 |
|
to be lost or to corrupt the managed handlers.<br><br> |
95 |
|
|
96 |
|
Another warning: setjmp is expensive if called inside a fast loop. |
97 |
|
|
98 |
Requires: |
Requires: |
99 |
#include "utilities/ascConfig.h" |
#include "utilities/ascConfig.h" |
115 |
# include <unistd.h> |
# include <unistd.h> |
116 |
#endif |
#endif |
117 |
|
|
118 |
|
#ifdef __WIN32__ |
119 |
|
# define FPRESET _fpreset() |
120 |
|
#else |
121 |
|
# define FPRESET (void)0 |
122 |
|
#endif |
123 |
|
|
124 |
typedef void SigHandlerFn(int); |
typedef void SigHandlerFn(int); |
125 |
/**< Signature of a signal handling function. */ |
/**< Signature of a signal handling function. */ |
126 |
|
|
229 |
* compiler/platform. |
* compiler/platform. |
230 |
*/ |
*/ |
231 |
|
|
232 |
|
ASC_DLLSPEC(int ) Asc_SignalHandlerPushDefault(int signum); |
233 |
ASC_DLLSPEC(int ) Asc_SignalHandlerPush(int signum, SigHandlerFn *func); |
ASC_DLLSPEC(int ) Asc_SignalHandlerPush(int signum, SigHandlerFn *func); |
234 |
/**< |
/**< |
235 |
* Adds a handler to the stack of signal handlers for the given signal. |
* Adds a handler to the stack of signal handlers for the given signal. |
252 |
* popping an unintended handler. |
* popping an unintended handler. |
253 |
*/ |
*/ |
254 |
|
|
255 |
|
ASC_DLLSPEC(int ) Asc_SignalHandlerPopDefault(int signum); |
256 |
ASC_DLLSPEC(int ) Asc_SignalHandlerPop(int signum, SigHandlerFn *func); |
ASC_DLLSPEC(int ) Asc_SignalHandlerPop(int signum, SigHandlerFn *func); |
257 |
/**< |
/**< |
258 |
* Removes the last-pushed handler from the stack for signum signal types. |
* Removes the last-pushed handler from the stack for signum signal types. |