X-Git-Url: http://git.itanic.dy.fi/?p=log-plotter;a=blobdiff_plain;f=event.c;fp=event.c;h=b3cbaf25ca4529cc0aa03b0eb60212b121616a37;hp=0000000000000000000000000000000000000000;hb=9abf935040bd368c4b3c1828a79691d200fd45a9;hpb=4daad2abbacb183bc39d7ef1220e86afe6068b5d diff --git a/event.c b/event.c new file mode 100644 index 0000000..b3cbaf2 --- /dev/null +++ b/event.c @@ -0,0 +1,98 @@ +#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; +} +