diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2012-02-27 10:35:31 -0800 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-02-27 10:35:31 -0800 |
commit | cad9bb230a5e0ad5fac828eda65527ba6413e7ce (patch) | |
tree | 2395d354547a9748eba050d0e3ddc1c93e79a2a1 /monitor | |
parent | a3877b43ee3bfadaf93c55e95ff4d9a5a4d0b891 (diff) | |
download | bluez-cad9bb230a5e0ad5fac828eda65527ba6413e7ce.tar.gz |
monitor: Use better signal integration
Diffstat (limited to 'monitor')
-rw-r--r-- | monitor/main.c | 17 | ||||
-rw-r--r-- | monitor/mainloop.c | 80 | ||||
-rw-r--r-- | monitor/mainloop.h | 5 |
3 files changed, 80 insertions, 22 deletions
diff --git a/monitor/main.c b/monitor/main.c index 5b21e60ab..b4781e8bc 100644 --- a/monitor/main.c +++ b/monitor/main.c @@ -34,12 +34,29 @@ #include "control.h" #include "hcidump.h" +static void signal_callback(int signum, void *user_data) +{ + switch (signum) { + case SIGINT: + case SIGTERM: + mainloop_quit(); + break; + } +} + int main(int argc, char *argv[]) { unsigned long filter_mask = 0; + sigset_t mask; mainloop_init(); + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + + mainloop_set_signal(&mask, signal_callback, NULL, NULL); + filter_mask |= PACKET_FILTER_SHOW_INDEX; filter_mask |= PACKET_FILTER_SHOW_TIME; filter_mask |= PACKET_FILTER_SHOW_ACL_DATA; diff --git a/monitor/mainloop.c b/monitor/mainloop.c index 7a16f0edd..1cc787eb5 100644 --- a/monitor/mainloop.c +++ b/monitor/mainloop.c @@ -62,6 +62,16 @@ struct timeout_data { void *user_data; }; +struct signal_data { + int fd; + sigset_t mask; + mainloop_signal_func callback; + mainloop_destroy_func destroy; + void *user_data; +}; + +static struct signal_data *signal_data; + void mainloop_init(void) { unsigned int i; @@ -81,6 +91,7 @@ void mainloop_quit(void) static void signal_callback(int fd, uint32_t events, void *user_data) { + struct signal_data *data = user_data; struct signalfd_siginfo si; ssize_t result; @@ -93,34 +104,28 @@ static void signal_callback(int fd, uint32_t events, void *user_data) if (result != sizeof(si)) return; - switch (si.ssi_signo) { - case SIGINT: - case SIGTERM: - mainloop_quit(); - break; - } + if (data->callback) + data->callback(si.ssi_signo, data->user_data); } int mainloop_run(void) { unsigned int i; - sigset_t mask; - int fd; - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); + if (signal_data) { + if (sigprocmask(SIG_BLOCK, &signal_data->mask, NULL) < 0) + return 1; - if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) - return 1; + signal_data->fd = signalfd(-1, &signal_data->mask, + SFD_NONBLOCK | SFD_CLOEXEC); + if (signal_data->fd < 0) + return 1; - fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); - if (fd < 0) - return 1; - - if (mainloop_add_fd(fd, EPOLLIN, signal_callback, NULL, NULL) < 0) { - close(fd); - return 1; + if (mainloop_add_fd(signal_data->fd, EPOLLIN, + signal_callback, signal_data, NULL) < 0) { + close(signal_data->fd); + return 1; + } } while (!epoll_terminate) { @@ -139,8 +144,13 @@ int mainloop_run(void) } } - mainloop_remove_fd(fd); - close(fd); + if (signal_data) { + mainloop_remove_fd(signal_data->fd); + close(signal_data->fd); + + if (signal_data->destroy) + signal_data->destroy(signal_data->user_data); + } for (i = 0; i < MAX_MAINLOOP_ENTRIES; i++) { struct mainloop_data *data = mainloop_list[i]; @@ -351,3 +361,29 @@ int mainloop_remove_timeout(int id) { return mainloop_remove_fd(id); } + +int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback, + void *user_data, mainloop_destroy_func destroy) +{ + struct signal_data *data; + + if (!mask || !callback) + return -EINVAL; + + data = malloc(sizeof(*data)); + if (!data) + return -ENOMEM; + + memset(data, 0, sizeof(*data)); + data->callback = callback; + data->destroy = destroy; + data->user_data = user_data; + + data->fd = -1; + memcpy(&data->mask, mask, sizeof(sigset_t)); + + free(signal_data); + signal_data = data; + + return 0; +} diff --git a/monitor/mainloop.h b/monitor/mainloop.h index 7a8869f93..04745d2d4 100644 --- a/monitor/mainloop.h +++ b/monitor/mainloop.h @@ -22,12 +22,14 @@ * */ +#include <signal.h> #include <sys/epoll.h> typedef void (*mainloop_destroy_func) (void *user_data); typedef void (*mainloop_event_func) (int fd, uint32_t events, void *user_data); typedef void (*mainloop_timeout_func) (int id, void *user_data); +typedef void (*mainloop_signal_func) (int signum, void *user_data); void mainloop_init(void); void mainloop_quit(void); @@ -42,3 +44,6 @@ int mainloop_add_timeout(unsigned int seconds, mainloop_timeout_func callback, void *user_data, mainloop_destroy_func destroy); int mainloop_modify_timeout(int fd, unsigned int seconds); int mainloop_remove_timeout(int id); + +int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback, + void *user_data, mainloop_destroy_func destroy); |