From: Michael Tremer Date: Sat, 10 Aug 2024 12:28:39 +0000 (+0000) Subject: daemon: Use the systemd event loop instead of epoll X-Git-Tag: 0.9.30~1219 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=403fe84f6c2f2f1328fc7c273f78dc4d24fabbf8;p=pakfire.git daemon: Use the systemd event loop instead of epoll This will allow us more flexiblity and already implements a lot of features. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/daemon.c b/src/libpakfire/daemon.c index 934ba2704..9fd9cc5af 100644 --- a/src/libpakfire/daemon.c +++ b/src/libpakfire/daemon.c @@ -20,7 +20,9 @@ #include #include -#include + +#include +#include #include #include @@ -34,11 +36,61 @@ struct pakfire_daemon { // Pakfire Build Service struct pakfire_buildservice* service; + + // Event Loop + sd_event* loop; }; +static int pakfire_daemon_terminate(sd_event_source* source, + const struct signalfd_siginfo* si, void* data) { + struct pakfire_daemon* daemon = data; + + CTX_DEBUG(daemon->ctx, "Received signal to terminate...\n"); + + return sd_event_exit(sd_event_source_get_event(source), 0); +} + +static int pakfire_daemon_setup_loop(struct pakfire_daemon* daemon) { + int r; + + // Fetch a reference to the default event loop + r = sd_event_default(&daemon->loop); + if (r < 0) { + CTX_ERROR(daemon->ctx, "Could not setup event loop: %s\n", strerror(-r)); + return 1; + } + + // Enable the watchdog + r = sd_event_set_watchdog(daemon->loop, 1); + if (r < 0) { + CTX_ERROR(daemon->ctx, "Could not activate watchdog: %s\n", strerror(-r)); + return 1; + } + + // Listen for SIGTERM + r = sd_event_add_signal(daemon->loop, NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, + pakfire_daemon_terminate, daemon); + if (r < 0) { + CTX_ERROR(daemon->ctx, "Could not register handling SIGTERM: %s\n", strerror(-r)); + return 1; + } + + // Listen for SIGINT + r = sd_event_add_signal(daemon->loop, NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, + pakfire_daemon_terminate, daemon); + if (r < 0) { + CTX_ERROR(daemon->ctx, "Could not register handling SIGINT: %s\n", strerror(-r)); + return 1; + } + + return 0; +} + static void pakfire_daemon_free(struct pakfire_daemon* daemon) { if (daemon->service) pakfire_buildservice_unref(daemon->service); + if (daemon->loop) + sd_event_unref(daemon->loop); if (daemon->ctx) pakfire_ctx_unref(daemon->ctx); free(daemon); @@ -59,6 +111,11 @@ int pakfire_daemon_create(struct pakfire_daemon** daemon, struct pakfire_ctx* ct // Initialize the reference counter d->nrefs = 1; + // Setup the event loop + r = pakfire_daemon_setup_loop(d); + if (r) + goto ERROR; + // Connect to the buildservice r = pakfire_buildservice_create(&d->service, d->ctx); if (r) @@ -91,66 +148,27 @@ struct pakfire_daemon* pakfire_daemon_unref(struct pakfire_daemon* daemon) { } static int pakfire_daemon_loop(struct pakfire_daemon* daemon) { - struct epoll_event events[EPOLL_MAX_EVENTS]; - struct epoll_event event; - int epollfd = -1; - int num = 0; - int fd = -1; - int e; int r; - // Setup epoll() - epollfd = epoll_create1(EPOLL_CLOEXEC); - if (epollfd < 0) { - CTX_ERROR(daemon->ctx, "Could not setup main loop: %s\n", strerror(errno)); - r = -errno; + // We are now ready + sd_notify(0, "READY=1\n" "STATUS=Ready..."); + + // Launch the event loop + r = sd_event_loop(daemon->loop); + if (r < 0) { + CTX_ERROR(daemon->ctx, "Could not run the event loop: %s\n", strerror(-r)); goto ERROR; } - CTX_DEBUG(daemon->ctx, "Entering main loop...\n"); - - // Main loop, loop, loop, looooop.... - for (;;) { - num = epoll_wait(epollfd, events, EPOLL_MAX_EVENTS, -1); - if (num < 1) { - switch (errno) { - case EINTR: - break; - - default: - CTX_ERROR(daemon->ctx, "epoll_wait() failed: %m\n"); - r = -errno; - break; - } - goto ERROR; - } - - // Handle all events - for (int i = 0; i < num; i++) { - fd = events[i].data.fd; - e = events[i].events; - - // XXX Do the work... - - // Remove the file descriptor if it has been closed - if (e & EPOLLHUP) { - r = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL); - if (r) { - CTX_ERROR(daemon->ctx, "Could not remove closed fd %d: %s\n", fd, strerror(errno)); - r = -errno; - goto ERROR; - } - } - } - } + // Let systemd know that we are shutting down + sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); -ERROR: - CTX_DEBUG(daemon->ctx, "Exited main loop...\n"); + return 0; - if (epollfd >= 0) - close(epollfd); +ERROR: + sd_notifyf(0, "ERRNO=%i", -r); - return r; + return 1; } int pakfire_daemon_main(struct pakfire_daemon* daemon) {