diff --git a/event-loop.c b/event-loop.c index ae72d08c..aacfebfe 100644 --- a/event-loop.c +++ b/event-loop.c @@ -4,13 +4,46 @@ #include #include #include +#include +#include #include #include #include "event-loop.h" -void init_event_loop(struct mako_event_loop *loop, sd_bus *bus, +static int init_signalfd() { + sigset_t mask; + int sfd; + + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGQUIT); + + if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) { + fprintf(stderr, "sigprocmask: %s", strerror(errno)); + return -1; + } + + if ((sfd = signalfd(-1, &mask, SFD_NONBLOCK)) == -1) { + fprintf(stderr, "signalfd: %s", strerror(errno)); + return -1; + } + + return sfd; +} + +bool init_event_loop(struct mako_event_loop *loop, sd_bus *bus, struct wl_display *display) { + if ((loop->sfd = init_signalfd()) == -1) { + return false; + } + + loop->fds[MAKO_EVENT_SIGNAL] = (struct pollfd){ + .fd = loop->sfd, + .events = POLLIN, + }; + loop->fds[MAKO_EVENT_DBUS] = (struct pollfd){ .fd = sd_bus_get_fd(bus), .events = POLLIN, @@ -29,6 +62,8 @@ void init_event_loop(struct mako_event_loop *loop, sd_bus *bus, loop->bus = bus; loop->display = display; wl_list_init(&loop->timers); + + return true; } void finish_event_loop(struct mako_event_loop *loop) { @@ -172,6 +207,10 @@ int run_event_loop(struct mako_event_loop *loop) { break; } + if (loop->fds[MAKO_EVENT_SIGNAL].revents & POLLIN) { + break; + } + if (!(loop->fds[MAKO_EVENT_WAYLAND].revents & POLLIN)) { wl_display_cancel_read(loop->display); } @@ -211,14 +250,3 @@ int run_event_loop(struct mako_event_loop *loop) { } return ret; } - -static void handle_stop_event_loop_timer(void *data) { - // No-op -} - -void stop_event_loop(struct mako_event_loop *loop) { - loop->running = false; - - // Wake up the event loop - add_event_loop_timer(loop, 0, handle_stop_event_loop_timer, NULL); -} diff --git a/include/event-loop.h b/include/event-loop.h index ef1a5bcb..b2bbb9e3 100644 --- a/include/event-loop.h +++ b/include/event-loop.h @@ -11,6 +11,7 @@ enum mako_event { MAKO_EVENT_DBUS, MAKO_EVENT_WAYLAND, MAKO_EVENT_TIMER, + MAKO_EVENT_SIGNAL, MAKO_EVENT_COUNT, // keep last }; @@ -18,6 +19,7 @@ struct mako_event_loop { struct pollfd fds[MAKO_EVENT_COUNT]; sd_bus *bus; struct wl_display *display; + int sfd; bool running; struct wl_list timers; // mako_timer::link @@ -34,11 +36,10 @@ struct mako_timer { struct wl_list link; // mako_event_loop::timers }; -void init_event_loop(struct mako_event_loop *loop, sd_bus *bus, +bool init_event_loop(struct mako_event_loop *loop, sd_bus *bus, struct wl_display *display); void finish_event_loop(struct mako_event_loop *loop); int run_event_loop(struct mako_event_loop *loop); -void stop_event_loop(struct mako_event_loop *loop); struct mako_timer *add_event_loop_timer(struct mako_event_loop *loop, int delay_ms, mako_event_loop_timer_func_t func, void *data); diff --git a/main.c b/main.c index 6b750c9a..dff0f28f 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ #define _POSIX_C_SOURCE 200809L #include -#include #include #include #include @@ -45,7 +44,11 @@ static bool init(struct mako_state *state) { finish_dbus(state); return false; } - init_event_loop(&state->event_loop, state->bus, state->display); + if (!init_event_loop(&state->event_loop, state->bus, state->display)) { + finish_dbus(state); + finish_wayland(state); + return false; + } wl_list_init(&state->notifications); return true; } @@ -62,10 +65,6 @@ static void finish(struct mako_state *state) { static struct mako_event_loop *event_loop = NULL; -static void handle_signal(int signum) { - stop_event_loop(event_loop); -} - int main(int argc, char *argv[]) { struct mako_state state = {0}; @@ -89,9 +88,6 @@ int main(int argc, char *argv[]) { } event_loop = &state.event_loop; - struct sigaction sa = { .sa_handler = handle_signal }; - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); ret = run_event_loop(&state.event_loop);