diff options
author | Kenny Levinsen <kl@kl.wtf> | 2020-08-31 03:14:51 +0200 |
---|---|---|
committer | Kenny Levinsen <kl@kl.wtf> | 2020-08-31 14:09:59 +0200 |
commit | d17632fadd1f901aa1fd41aceb06663019d73ade (patch) | |
tree | a26c6a73f8231dc5dfd3132027c8ecce36453938 /seatd | |
parent | bbfb770c73498413055c7af8d3e1b8db36560016 (diff) |
poller: Convert to linked_list
Diffstat (limited to 'seatd')
-rw-r--r-- | seatd/poller.c | 203 |
1 files changed, 74 insertions, 129 deletions
diff --git a/seatd/poller.c b/seatd/poller.c index 0631f4b..74d5d89 100644 --- a/seatd/poller.c +++ b/seatd/poller.c @@ -6,11 +6,13 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> -#include "list.h" +#include "linked_list.h" #include "poller.h" struct event_source_fd { + struct linked_list link; // poller::fds const struct event_source_fd_impl *impl; event_source_fd_func_t func; @@ -20,9 +22,11 @@ struct event_source_fd { struct poller *poller; bool killed; + ssize_t pollfd_idx; }; struct event_source_signal { + struct linked_list link; // poller::signals const struct event_source_signal_impl *impl; event_source_signal_func_t func; @@ -40,38 +44,21 @@ struct poller *global_poller = NULL; void poller_init(struct poller *poller) { assert(global_poller == NULL); - list_init(&poller->fds); - list_init(&poller->new_fds); - list_init(&poller->signals); - list_init(&poller->new_signals); + linked_list_init(&poller->fds); + linked_list_init(&poller->signals); + poller->pollfds = NULL; + poller->pollfds_len = 0; + poller->fd_event_sources = 0; global_poller = poller; } int poller_finish(struct poller *poller) { - for (size_t idx = 0; idx < poller->fds.length; idx++) { - struct event_source_fd *bpfd = poller->fds.items[idx]; + while (!linked_list_empty(&poller->fds)) { + struct event_source_fd *bpfd = (struct event_source_fd *)poller->fds.next; free(bpfd); } - list_free(&poller->fds); - for (size_t idx = 0; idx < poller->new_fds.length; idx++) { - struct event_source_fd *bpfd = poller->new_fds.items[idx]; - free(bpfd); - } - list_free(&poller->new_fds); - for (size_t idx = 0; idx < poller->signals.length; idx++) { - struct event_source_signal *bps = poller->signals.items[idx]; - - struct sigaction sa; - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(bps->signal, &sa, NULL); - - free(bps); - } - list_free(&poller->signals); - for (size_t idx = 0; idx < poller->new_signals.length; idx++) { - struct event_source_signal *bps = poller->new_signals.items[idx]; + while (!linked_list_empty(&poller->signals)) { + struct event_source_signal *bps = (struct event_source_signal *)poller->signals.next; struct sigaction sa; sa.sa_handler = SIG_DFL; @@ -81,7 +68,6 @@ int poller_finish(struct poller *poller) { free(bps); } - list_free(&poller->new_signals); free(poller->pollfds); return 0; } @@ -115,24 +101,31 @@ static uint32_t poll_mask_to_event_mask(int poll_mask) { } static int regenerate_pollfds(struct poller *poller) { - if (poller->pollfds_len != poller->fds.length) { - struct pollfd *fds = calloc(poller->fds.length, sizeof(struct pollfd)); + if (!poller->pollfds_dirty) { + return 0; + } + + if (poller->fd_event_sources > poller->pollfds_len) { + struct pollfd *fds = calloc(poller->fd_event_sources, sizeof(struct pollfd)); if (fds == NULL) { return -1; } free(poller->pollfds); poller->pollfds = fds; - poller->pollfds_len = poller->fds.length; + poller->pollfds_len = poller->fd_event_sources; } - for (size_t idx = 0; idx < poller->fds.length; idx++) { - struct event_source_fd *bpfd = poller->fds.items[idx]; - poller->pollfds[idx] = (struct pollfd){ + ssize_t idx = 0; + for (struct linked_list *elem = poller->fds.next; elem != &poller->fds; elem = elem->next) { + struct event_source_fd *bpfd = (struct event_source_fd *)elem; + bpfd->pollfd_idx = idx++; + poller->pollfds[bpfd->pollfd_idx] = (struct pollfd){ .fd = bpfd->fd, .events = event_mask_to_poll_mask(bpfd->mask), }; } + poller->pollfds_dirty = false; return 0; } @@ -147,31 +140,19 @@ struct event_source_fd *poller_add_fd(struct poller *poller, int fd, uint32_t ma bpfd->data = data; bpfd->func = func; bpfd->poller = poller; - poller->dirty = true; - if (poller->inpoll) { - list_add(&poller->new_fds, bpfd); - } else { - list_add(&poller->fds, bpfd); - regenerate_pollfds(poller); - } + bpfd->pollfd_idx = -1; + poller->fd_event_sources += 1; + poller->pollfds_dirty = true; + linked_list_insert(&poller->fds, &bpfd->link); return (struct event_source_fd *)bpfd; } int event_source_fd_destroy(struct event_source_fd *event_source) { struct event_source_fd *bpfd = (struct event_source_fd *)event_source; struct poller *poller = bpfd->poller; - int idx = list_find(&poller->fds, event_source); - if (idx == -1) { - return -1; - } - poller->dirty = true; - if (poller->inpoll) { - bpfd->killed = true; - } else { - list_del(&poller->fds, idx); - free(bpfd); - regenerate_pollfds(poller); - } + poller->fd_event_sources -= 1; + poller->pollfds_dirty = true; + bpfd->killed = true; return 0; } @@ -179,11 +160,7 @@ int event_source_fd_update(struct event_source_fd *event_source, uint32_t mask) struct event_source_fd *bpfd = (struct event_source_fd *)event_source; struct poller *poller = bpfd->poller; event_source->mask = mask; - - poller->dirty = true; - if (!poller->inpoll) { - regenerate_pollfds(poller); - } + poller->pollfds_dirty = true; return 0; } @@ -191,9 +168,9 @@ static void signal_handler(int sig) { if (global_poller == NULL) { return; } - - for (size_t idx = 0; idx < global_poller->signals.length; idx++) { - struct event_source_signal *bps = global_poller->signals.items[idx]; + for (struct linked_list *elem = global_poller->signals.next; + elem != &global_poller->signals; elem = elem->next) { + struct event_source_signal *bps = (struct event_source_signal *)elem; if (bps->signal == sig) { bps->raised = true; } @@ -208,32 +185,18 @@ struct event_source_signal *poller_add_signal(struct poller *poller, int signal, return NULL; } - int refcnt = 0; - for (size_t idx = 0; idx < poller->signals.length; idx++) { - struct event_source_signal *bps = poller->signals.items[idx]; - if (bps->signal == signal) { - refcnt++; - } - } - bps->signal = signal; bps->data = data; bps->func = func; bps->poller = poller; - if (refcnt == 0) { - struct sigaction sa; - sa.sa_handler = &signal_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(signal, &sa, NULL); - } + struct sigaction sa; + sa.sa_handler = &signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(signal, &sa, NULL); - if (poller->inpoll) { - list_add(&poller->new_signals, bps); - } else { - list_add(&poller->signals, bps); - } + linked_list_insert(&poller->signals, &bps->link); return (struct event_source_signal *)bps; } @@ -242,15 +205,11 @@ int event_source_signal_destroy(struct event_source_signal *event_source) { struct event_source_signal *bps = (struct event_source_signal *)event_source; struct poller *poller = bps->poller; - int idx = list_find(&poller->signals, event_source); - if (idx == -1) { - return -1; - } - int refcnt = 0; - for (size_t idx = 0; idx < poller->signals.length; idx++) { - struct event_source_signal *b = poller->signals.items[idx]; - if (b->signal == bps->signal) { + for (struct linked_list *elem = poller->signals.next; elem != &poller->signals; + elem = elem->next) { + struct event_source_signal *b = (struct event_source_signal *)elem; + if (b->signal == bps->signal && !b->killed) { refcnt++; } } @@ -263,77 +222,63 @@ int event_source_signal_destroy(struct event_source_signal *event_source) { sigaction(bps->signal, &sa, NULL); } - if (poller->inpoll) { - bps->killed = true; - } else { - list_del(&poller->signals, idx); - free(bps); - } + bps->killed = true; return 0; } int poller_poll(struct poller *poller) { - if (poll(poller->pollfds, poller->fds.length, -1) == -1 && errno != EINTR) { + if (regenerate_pollfds(poller) == -1) { return -1; } - poller->inpoll = true; + if (poll(poller->pollfds, poller->fd_event_sources, -1) == -1 && errno != EINTR) { + return -1; + } - for (size_t idx = 0; idx < poller->fds.length; idx++) { - short revents = poller->pollfds[idx].revents; + for (struct linked_list *elem = poller->fds.next; elem != &poller->fds; elem = elem->next) { + struct event_source_fd *bpfd = (struct event_source_fd *)elem; + if (bpfd->pollfd_idx == -1 || bpfd->killed) { + continue; + } + short revents = poller->pollfds[bpfd->pollfd_idx].revents; if (revents == 0) { continue; } - struct event_source_fd *bpfd = poller->fds.items[idx]; - bpfd->func(poller->pollfds[idx].fd, poll_mask_to_event_mask(revents), bpfd->data); + bpfd->func(poller->pollfds[bpfd->pollfd_idx].fd, poll_mask_to_event_mask(revents), + bpfd->data); } - for (size_t idx = 0; idx < poller->signals.length; idx++) { - struct event_source_signal *bps = poller->signals.items[idx]; - if (!bps->raised) { + for (struct linked_list *elem = poller->signals.next; elem != &poller->signals; + elem = elem->next) { + struct event_source_signal *bps = (struct event_source_signal *)elem; + if (!bps->raised || bps->killed) { continue; } bps->func(bps->signal, bps->data); bps->raised = false; } - poller->inpoll = false; - - for (size_t idx = 0; idx < poller->fds.length; idx++) { - struct event_source_fd *bpfd = poller->fds.items[idx]; + for (struct linked_list *elem = poller->fds.next; elem != &poller->fds; elem = elem->next) { + struct event_source_fd *bpfd = (struct event_source_fd *)elem; if (!bpfd->killed) { continue; } - list_del(&poller->fds, idx); + elem = elem->prev; + linked_list_remove(&bpfd->link); free(bpfd); - idx--; } - for (size_t idx = 0; idx < poller->signals.length; idx++) { - struct event_source_signal *bps = poller->signals.items[idx]; + for (struct linked_list *elem = poller->signals.next; elem != &poller->signals; + elem = elem->next) { + struct event_source_signal *bps = (struct event_source_signal *)elem; if (!bps->killed) { continue; } - list_del(&poller->signals, idx); + elem = elem->prev; + linked_list_remove(&bps->link); free(bps); - idx--; - } - - if (poller->new_fds.length > 0) { - list_concat(&poller->fds, &poller->new_fds); - list_truncate(&poller->new_fds); - } - - if (poller->new_signals.length > 0) { - list_concat(&poller->signals, &poller->new_signals); - list_truncate(&poller->new_signals); - } - - if (poller->dirty) { - regenerate_pollfds(poller); - poller->dirty = false; } return 0; |