summaryrefslogtreecommitdiffstats
path: root/swaybar/event_loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/event_loop.c')
-rw-r--r--swaybar/event_loop.c42
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,
72} 72}
73 73
74bool remove_event(int fd) { 74bool remove_event(int fd) {
75 int index = -1; 75 /*
76 * Instead of removing events immediately, we mark them for deletion
77 * and clean them up later. This is so we can call remove_event inside
78 * an event callback safely.
79 */
76 for (int i = 0; i < event_loop.fds.length; ++i) { 80 for (int i = 0; i < event_loop.fds.length; ++i) {
77 if (event_loop.fds.items[i].fd == fd) { 81 if (event_loop.fds.items[i].fd == fd) {
78 index = i; 82 event_loop.fds.items[i].fd = -1;
83 return true;
79 } 84 }
80 } 85 }
81 if (index != -1) { 86 return false;
82 free(event_loop.items->items[index]);
83
84 --event_loop.fds.length;
85 memmove(&event_loop.fds.items[index], &event_loop.fds.items[index + 1],
86 sizeof(struct pollfd) * event_loop.fds.length - index);
87
88 list_del(event_loop.items, index);
89 return true;
90 } else {
91 return false;
92 }
93} 87}
94 88
95static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { 89static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) {
@@ -118,11 +112,29 @@ void event_loop_poll() {
118 struct pollfd pfd = event_loop.fds.items[i]; 112 struct pollfd pfd = event_loop.fds.items[i];
119 struct event_item *item = (struct event_item *)event_loop.items->items[i]; 113 struct event_item *item = (struct event_item *)event_loop.items->items[i];
120 114
121 if (pfd.revents & pfd.events) { 115 // Always send these events
116 unsigned events = pfd.events | POLLHUP | POLLERR;
117
118 if (pfd.revents & events) {
122 item->cb(pfd.fd, pfd.revents, item->data); 119 item->cb(pfd.fd, pfd.revents, item->data);
123 } 120 }
124 } 121 }
125 122
123 // Cleanup removed events
124 int end = 0;
125 int length = event_loop.fds.length;
126 for (int i = 0; i < length; ++i) {
127 if (event_loop.fds.items[i].fd == -1) {
128 free(event_loop.items->items[i]);
129 list_del(event_loop.items, i);
130 --event_loop.fds.length;
131 } else if (end != i) {
132 event_loop.fds.items[end++] = event_loop.fds.items[i];
133 } else {
134 end = i + 1;
135 }
136 }
137
126 // check timers 138 // check timers
127 // not tested, but seems to work 139 // not tested, but seems to work
128 for (int i = 0; i < event_loop.timers->length; ++i) { 140 for (int i = 0; i < event_loop.timers->length; ++i) {