diff options
author | Felix Fietkau <nbd@nbd.name> | 2023-05-23 13:24:33 +0300 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2023-05-23 16:32:36 +0300 |
commit | 75a3b870cace1171faf57bd55e5a9a2f1564f757 (patch) | |
tree | 35c63732cdc5920269466c179258409d49c811d7 | |
parent | 362951a2d96e5c00a2ca5f9495d18cf16f43bc68 (diff) |
uloop: add support for integrating with a different event loop
- support reading the next timeout in order to determine the poll timeout
- add a callback for fd add/delete/update
Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r-- | uloop-epoll.c | 1 | ||||
-rw-r--r-- | uloop-kqueue.c | 4 | ||||
-rw-r--r-- | uloop.c | 38 | ||||
-rw-r--r-- | uloop.h | 2 |
4 files changed, 32 insertions, 13 deletions
diff --git a/uloop-epoll.c b/uloop-epoll.c index 609ca6e..70e45e4 100644 --- a/uloop-epoll.c +++ b/uloop-epoll.c @@ -53,7 +53,6 @@ static int register_poll(struct uloop_fd *fd, unsigned int flags) ev.events |= EPOLLET; ev.data.ptr = fd; - fd->flags = flags; return epoll_ctl(poll_fd, op, fd->fd, &ev); } diff --git a/uloop-kqueue.c b/uloop-kqueue.c index ba5595b..c1275b0 100644 --- a/uloop-kqueue.c +++ b/uloop-kqueue.c @@ -66,6 +66,9 @@ static int register_kevent(struct uloop_fd *fd, unsigned int flags) if (changed & ULOOP_EDGE_TRIGGER) changed |= flags; + if (!changed) + return 0; + if (changed & ULOOP_READ) { kflags = get_flags(flags, ULOOP_READ); EV_SET(&ev[nev++], fd->fd, EVFILT_READ, kflags, 0, 0, fd); @@ -79,7 +82,6 @@ static int register_kevent(struct uloop_fd *fd, unsigned int flags) if (!flags) fl |= EV_DELETE; - fd->flags = flags; if (kevent(poll_fd, ev, nev, NULL, fl, &timeout) == -1) return -1; @@ -67,6 +67,8 @@ static struct uloop_fd_event cur_fds[ULOOP_MAX_EVENTS]; static int cur_fd, cur_nfds; static int uloop_run_depth = 0; +uloop_fd_handler uloop_fd_set_cb = NULL; + int uloop_fd_add(struct uloop_fd *sock, unsigned int flags); #ifdef USE_KQUEUE @@ -161,7 +163,7 @@ static bool uloop_fd_stack_event(struct uloop_fd *fd, int events) return false; } -static void uloop_run_events(int timeout) +static void uloop_run_events(int64_t timeout) { struct uloop_fd_event *cur; struct uloop_fd *fd; @@ -223,6 +225,10 @@ int uloop_fd_add(struct uloop_fd *sock, unsigned int flags) if (ret < 0) goto out; + if (uloop_fd_set_cb) + uloop_fd_set_cb(sock, flags); + + sock->flags = flags; sock->registered = true; sock->eof = false; sock->error = false; @@ -245,7 +251,11 @@ int uloop_fd_delete(struct uloop_fd *fd) if (!fd->registered) return 0; + if (uloop_fd_set_cb) + uloop_fd_set_cb(fd, 0); + fd->registered = false; + fd->flags = 0; uloop_fd_stack_event(fd, -1); return __uloop_fd_delete(fd); } @@ -495,30 +505,40 @@ static void uloop_setup_signals(bool add) uloop_ignore_signal(SIGPIPE, add); } -static int uloop_get_next_timeout(struct timeval *tv) +int uloop_get_next_timeout(void) { struct uloop_timeout *timeout; + struct timeval tv; int64_t diff; if (list_empty(&timeouts)) return -1; + uloop_gettime(&tv); + timeout = list_first_entry(&timeouts, struct uloop_timeout, list); - diff = tv_diff(&timeout->time, tv); + diff = tv_diff(&timeout->time, &tv); if (diff < 0) return 0; + if (diff > INT_MAX) + return INT_MAX; return diff; } -static void uloop_process_timeouts(struct timeval *tv) +static void uloop_process_timeouts(void) { struct uloop_timeout *t; + struct timeval tv; + + if (list_empty(&timeouts)) + return; + uloop_gettime(&tv); while (!list_empty(&timeouts)) { t = list_first_entry(&timeouts, struct uloop_timeout, list); - if (tv_diff(&t->time, tv) > 0) + if (tv_diff(&t->time, &tv) > 0) break; uloop_timeout_cancel(t); @@ -551,15 +571,13 @@ bool uloop_cancelling(void) int uloop_run_timeout(int timeout) { int next_time = 0; - struct timeval tv; uloop_run_depth++; uloop_status = 0; uloop_cancelled = false; do { - uloop_gettime(&tv); - uloop_process_timeouts(&tv); + uloop_process_timeouts(); if (do_sigchld) uloop_handle_processes(); @@ -567,9 +585,7 @@ int uloop_run_timeout(int timeout) if (uloop_cancelled) break; - uloop_gettime(&tv); - - next_time = uloop_get_next_timeout(&tv); + next_time = uloop_get_next_timeout(); if (timeout >= 0 && (next_time < 0 || timeout < next_time)) next_time = timeout; uloop_run_events(next_time); @@ -85,10 +85,12 @@ struct uloop_process extern bool uloop_cancelled; extern bool uloop_handle_sigchld; +extern uloop_fd_handler uloop_fd_set_cb; int uloop_fd_add(struct uloop_fd *sock, unsigned int flags); int uloop_fd_delete(struct uloop_fd *sock); +int uloop_get_next_timeout(void); int uloop_timeout_add(struct uloop_timeout *timeout); int uloop_timeout_set(struct uloop_timeout *timeout, int msecs); int uloop_timeout_cancel(struct uloop_timeout *timeout); |