Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105// SPDX-License-Identifier: LGPL-2.1+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <signal.h>#include <sys/epoll.h>#include "mainloop.h"#include "log.h"
static int epfd = -1;static sig_atomic_t exit_mainloop;
struct mainloop_data { mainloop_callback_t cb; void *data; int fd;};
#define MAX_EVENTS 10
int mainloop(unsigned int timeout){ int i, nfds; struct epoll_event events[MAX_EVENTS]; struct mainloop_data *md;
if (epfd < 0) return -1;
for (;;) {
nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout);
if (exit_mainloop || !nfds) return 0;
if (nfds < 0) { if (errno == EINTR) continue; return -1; }
for (i = 0; i < nfds; i++) { md = events[i].data.ptr;
if (md->cb(md->fd, md->data) > 0) return 0; } }}
int mainloop_add(int fd, mainloop_callback_t cb, void *data){ struct epoll_event ev = { .events = EPOLLIN, };
struct mainloop_data *md;
md = malloc(sizeof(*md)); if (!md) return -1;
md->data = data; md->cb = cb; md->fd = fd;
ev.data.ptr = md;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0) { free(md); return -1; }
return 0;}
int mainloop_del(int fd){ if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0) return -1;
return 0;}
int mainloop_init(void){ epfd = epoll_create(2); if (epfd < 0) return -1;
return 0;}
void mainloop_exit(void){ exit_mainloop = 1;}
void mainloop_fini(void){ close(epfd);}