1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#include "platform.h"
extern struct GC_state gcState;
static void handler (int signum) {
GC_handler (&gcState, signum);
}
enum {
#if (defined (SA_ONSTACK))
SA_FLAGS = SA_ONSTACK,
#else
SA_FLAGS = 0,
#endif
};
Int Posix_Signal_default (Int signum) {
struct sigaction sa;
sigdelset (&gcState.signalsHandled, signum);
memset (&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sa.sa_flags = SA_FLAGS;
return sigaction (signum, &sa, NULL);
}
bool Posix_Signal_isGCPending () {
Bool res;
res = gcState.gcSignalIsPending;
if (DEBUG_SIGNALS)
fprintf (stderr, "%s = Posix_Signal_isGCPending ()\n",
boolToString (res));
return res;
}
Bool Posix_Signal_isPending (Int signum) {
return sigismember (&gcState.signalsPending, signum);
}
Int Posix_Signal_handle (Int signum) {
static struct sigaction sa;
sigaddset (&gcState.signalsHandled, signum);
memset (&sa, 0, sizeof(sa));
/* The mask must be full because GC_handler reads and writes
* s->signalsPending (else there is a race condition).
*/
sigfillset (&sa.sa_mask);
sa.sa_handler = handler;
sa.sa_flags = SA_FLAGS;
return sigaction (signum, &sa, NULL);
}
void Posix_Signal_handleGC () {
gcState.handleGCSignal = TRUE;
}
Int Posix_Signal_ignore (Int signum) {
struct sigaction sa;
sigdelset (&gcState.signalsHandled, signum);
memset (&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
sa.sa_flags = SA_FLAGS;
return sigaction (signum, &sa, NULL);
}
Int Posix_Signal_isDefault (Int signum, Bool *isDef) {
Int res;
struct sigaction sa;
sa.sa_flags = SA_FLAGS;
res = sigaction (signum, NULL, &sa);
*isDef = sa.sa_handler == SIG_DFL;
return res;
}
void Posix_Signal_resetPending () {
if (DEBUG_SIGNALS)
fprintf (stderr, "Posix_Signal_resetPending ()\n");
sigemptyset (&gcState.signalsPending);
gcState.gcSignalIsPending = FALSE;
}
static sigset_t set;
Int Posix_Signal_sigaddset (Int signum) {
return sigaddset (&set, signum);
}
Int Posix_Signal_sigdelset (Int signum) {
return sigdelset (&set, signum);
}
Int Posix_Signal_sigemptyset () {
return sigemptyset (&set);
}
Int Posix_Signal_sigfillset () {
return sigfillset (&set);
}
Int Posix_Signal_sigismember (Int signum) {
return sigismember (&set, signum);
}
Int Posix_Signal_sigprocmask (Int how) {
return sigprocmask (how, &set, &set);
}
void Posix_Signal_suspend () {
int res;
res = sigsuspend (&set);
assert (-1 == res);
}
|