source: signal.c @ 08e9842

release-1.10release-1.8release-1.9
Last change on this file since 08e9842 was 08e9842, checked in by David Benjamin <davidben@mit.edu>, 14 years ago
Cleanly destroy the signal thread on shutdown This isn't strictly necessary here, but we should probably be in the habit of safely cleaning up our helper threads. Switch the implementation from GThread to pthreads directly. The cleanest way to kill a signaling thread is to send it SIGTERM with pthread_kill, but GThread doesn't expose that and gives no way to get at the pthread_t.
  • 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
10static void (*signal_cb)(int, void*);
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.) */
[3535a6e]21void owl_signal_init(const sigset_t *set, void (*callback)(int, 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) {
[81db142]43     int signal;
[3535a6e]44    int ret;
45
46    ret = sigwait(&signal_set, &signal);
47    /* TODO: Print an error? man page claims it never errors. */
48    if (ret != 0)
49      continue;
50
[81db142]51    signal_cb(signal, signal_cbdata);
[08e9842]52    /* Die on SIGTERM. */
53    if (signal == SIGTERM)
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.