source: signal.c @ ea68035

release-1.8release-1.9
Last change on this file since ea68035 was 1d21d9f, checked in by David Benjamin <davidben@mit.edu>, 11 years ago
Use sigwaitinfo instead of sigwait Eh, may as well give the signal handlers a little bit more rope.
  • Property mode set to 100644
File size: 1.6 KB
RevLine 
[6bd485e]1#include <errno.h>
[3535a6e]2#include <pthread.h>
3#include <signal.h>
4#include <stdio.h>
5#include <stdlib.h>
6
[08e9842]7static pthread_t signal_thread;
[3535a6e]8static sigset_t signal_set;
9
[1d21d9f]10static void (*signal_cb)(const siginfo_t*, void*);
[3535a6e]11static void *signal_cbdata;
12
[08e9842]13static void *signal_thread_func(void *data);
[3535a6e]14
[81db142]15/* Initializes the signal thread to listen for 'set' on a dedicated
16 * thread. 'callback' is called *on the signal thread* when a signal
17 * is received.
18 *
19 * This function /must/ be called before any other threads are
20 * created. (Otherwise the signals will not get blocked correctly.) */
[1d21d9f]21void owl_signal_init(const sigset_t *set, void (*callback)(const siginfo_t*, void*), void *data) {
[6bd485e]22  int ret;
[3535a6e]23
24  signal_set = *set;
25  signal_cb = callback;
26  signal_cbdata = data;
27  /* Block these signals in all threads, so we can get them. */
[6bd485e]28  if ((ret = pthread_sigmask(SIG_BLOCK, set, NULL)) != 0) {
29    errno = ret;
30    perror("pthread_sigmask");
31  }
[3535a6e]32  /* Spawn a dedicated thread to sigwait. */
[08e9842]33  if ((ret = pthread_create(&signal_thread, NULL,
34                            signal_thread_func, NULL)) != 0) {
35    errno = ret;
36    perror("pthread_create");
[3535a6e]37    exit(1);
38  }
39}
40
[08e9842]41static void *signal_thread_func(void *data) {
[3535a6e]42  while (1) {
[1d21d9f]43    siginfo_t siginfo;
[3535a6e]44    int ret;
45
[1d21d9f]46    ret = sigwaitinfo(&signal_set, &siginfo);
47    /* TODO: Print an error? */
48    if (ret < 0)
[3535a6e]49      continue;
50
[1d21d9f]51    signal_cb(&siginfo, signal_cbdata);
[08e9842]52    /* Die on SIGTERM. */
[1d21d9f]53    if (siginfo.si_signo == SIGTERM)
[08e9842]54      break;
[3535a6e]55  }
56  return NULL;
57}
[08e9842]58
59void owl_signal_shutdown(void) {
60  pthread_kill(signal_thread, SIGTERM);
61  pthread_join(signal_thread, NULL);
62}
Note: See TracBrowser for help on using the repository browser.