#include #include #include "event.h" #include "trace.h" static int epoll_fd = -1; static int init_event_handler(void) { epoll_fd = epoll_create(1); if (epoll_fd < 0) { pr_err("Failed to create epoll socket: %m\n"); return -1; } return 0; } int register_event_handler(struct eventhandler_entry *handler) { struct epoll_event ev; int ret = 0; if (epoll_fd < 0) ret = init_event_handler(); if (ret < 0) return ret; if (handler->fd < 0) { pr_err("Invalid file descriptor of %d for handler %s\n", handler->fd, handler->name); return -1; } if (!handler->handle_event) { pr_err("Handler %s missing callback function\n", handler->name); return -1; } pr_debug("Registering handler for \"%s\", fd=%d\n", handler->name, handler->fd); ev.data.fd = handler->fd; ev.data.ptr = handler; ev.events = handler->events; ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, handler->fd, &ev); if (ret) { pr_err("Failed to add epoll_fd: %m\n"); return -1; } return 0; } int poll_events(int timeout_ms) { struct epoll_event event; struct eventhandler_entry *handler; int ret; ret = epoll_wait(epoll_fd, &event, 1, timeout_ms); if (ret == -1) { if (errno != EINTR) { pr_err("epoll_wait: %m\n"); return -1; } /* * If epoll_wait() was interrupted, better start * everything again from the beginning */ return 0; } if (ret == 0) { pr_info("Timed out\n"); goto out; } handler = event.data.ptr; if (!handler || !handler->handle_event) { pr_err("Corrupted event handler for fd %d\n", event.data.fd); goto out; } pr_debug("Running handler %s to handle events from fd %d\n", handler->name, handler->fd); handler->handle_event(handler); out: return ret; }