diff options
author | Drew DeVault <[email protected]> | 2018-04-21 14:45:33 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2018-04-21 14:45:33 +0200 |
commit | ce70b9c45c65ae09e2d093520683ba77730d3368 (patch) | |
tree | f57dd4468446b9f07e55657912ff7843e7451ab3 /swaybar/event_loop.c | |
parent | 7d43cedc95a76cc4d466f76f0023383abd6ddab0 (diff) | |
parent | c63554885e4aae4e1c8f97ffbd53160f3eb99510 (diff) |
Merge pull request #1835 from ascent12/swaybar_status_err
Swaybar fix
Diffstat (limited to 'swaybar/event_loop.c')
-rw-r--r-- | swaybar/event_loop.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/swaybar/event_loop.c b/swaybar/event_loop.c index 748372ed..bc4053be 100644 --- a/swaybar/event_loop.c +++ b/swaybar/event_loop.c @@ -72,24 +72,18 @@ void add_event(int fd, short mask, } bool remove_event(int fd) { - int index = -1; + /* + * Instead of removing events immediately, we mark them for deletion + * and clean them up later. This is so we can call remove_event inside + * an event callback safely. + */ for (int i = 0; i < event_loop.fds.length; ++i) { if (event_loop.fds.items[i].fd == fd) { - index = i; + event_loop.fds.items[i].fd = -1; + return true; } } - if (index != -1) { - free(event_loop.items->items[index]); - - --event_loop.fds.length; - memmove(&event_loop.fds.items[index], &event_loop.fds.items[index + 1], - sizeof(struct pollfd) * event_loop.fds.length - index); - - list_del(event_loop.items, index); - return true; - } else { - return false; - } + return false; } static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { @@ -118,11 +112,29 @@ void event_loop_poll() { struct pollfd pfd = event_loop.fds.items[i]; struct event_item *item = (struct event_item *)event_loop.items->items[i]; - if (pfd.revents & pfd.events) { + // Always send these events + unsigned events = pfd.events | POLLHUP | POLLERR; + + if (pfd.revents & events) { item->cb(pfd.fd, pfd.revents, item->data); } } + // Cleanup removed events + int end = 0; + int length = event_loop.fds.length; + for (int i = 0; i < length; ++i) { + if (event_loop.fds.items[i].fd == -1) { + free(event_loop.items->items[i]); + list_del(event_loop.items, i); + --event_loop.fds.length; + } else if (end != i) { + event_loop.fds.items[end++] = event_loop.fds.items[i]; + } else { + end = i + 1; + } + } + // check timers // not tested, but seems to work for (int i = 0; i < event_loop.timers->length; ++i) { |