aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/event_loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/event_loop.c')
-rw-r--r--swaybar/event_loop.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/swaybar/event_loop.c b/swaybar/event_loop.c
index 0d1be1da..bde8203f 100644
--- a/swaybar/event_loop.c
+++ b/swaybar/event_loop.c
@@ -20,6 +20,19 @@ struct timer_item {
20 void *data; 20 void *data;
21}; 21};
22 22
23enum state_item_flags {
24 ITEM_IS_FD,
25 ITEM_IS_TIMER,
26};
27
28struct state_item {
29 enum state_item_flags flags;
30 union {
31 int fd;
32 timer_t timer;
33 } inner;
34};
35
23static struct { 36static struct {
24 // The order of each must be kept consistent 37 // The order of each must be kept consistent
25 struct { /* pollfd array */ 38 struct { /* pollfd array */
@@ -31,6 +44,9 @@ static struct {
31 44
32 // Timer list 45 // Timer list
33 list_t *timers; 46 list_t *timers;
47
48 // List of state changes at the end of each iteration
49 list_t *state;
34} event_loop; 50} event_loop;
35 51
36void add_timer(timer_t timer, 52void add_timer(timer_t timer,
@@ -72,7 +88,7 @@ void add_event(int fd, short mask,
72 return; 88 return;
73} 89}
74 90
75bool remove_event(int fd) { 91static void _remove_event(int fd) {
76 int index = -1; 92 int index = -1;
77 for (int i = 0; i < event_loop.fds.length; ++i) { 93 for (int i = 0; i < event_loop.fds.length; ++i) {
78 if (event_loop.fds.items[i].fd == fd) { 94 if (event_loop.fds.items[i].fd == fd) {
@@ -87,12 +103,16 @@ bool remove_event(int fd) {
87 sizeof(struct pollfd) * event_loop.fds.length - index); 103 sizeof(struct pollfd) * event_loop.fds.length - index);
88 104
89 list_del(event_loop.items, index); 105 list_del(event_loop.items, index);
90 return true;
91 } else {
92 return false;
93 } 106 }
94} 107}
95 108
109void remove_event(int fd) {
110 struct state_item *item = malloc(sizeof(struct state_item));
111 item->flags = ITEM_IS_FD;
112 item->inner.fd = fd;
113 list_add(event_loop.state, item);
114}
115
96static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { 116static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) {
97 const struct timer_item *timer_item = _timer_item; 117 const struct timer_item *timer_item = _timer_item;
98 const timer_t *timer = _timer; 118 const timer_t *timer = _timer;
@@ -102,14 +122,19 @@ static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) {
102 return -1; 122 return -1;
103 } 123 }
104} 124}
105bool remove_timer(timer_t timer) { 125static void _remove_timer(timer_t timer) {
106 int index = list_seq_find(event_loop.timers, timer_item_timer_cmp, &timer); 126 int index = list_seq_find(event_loop.timers, timer_item_timer_cmp, &timer);
107 if (index != -1) { 127 if (index != -1) {
108 free(event_loop.timers->items[index]); 128 free(event_loop.timers->items[index]);
109 list_del(event_loop.timers, index); 129 list_del(event_loop.timers, index);
110 return true;
111 } 130 }
112 return false; 131}
132
133void remove_timer(timer_t timer) {
134 struct state_item *item = malloc(sizeof(struct state_item));
135 item->flags = ITEM_IS_TIMER;
136 item->inner.timer = timer;
137 list_add(event_loop.state, item);
113} 138}
114 139
115void event_loop_poll() { 140void event_loop_poll() {
@@ -133,6 +158,19 @@ void event_loop_poll() {
133 item->cb(item->timer, item->data); 158 item->cb(item->timer, item->data);
134 } 159 }
135 } 160 }
161
162 // Remove all requested items from the event loop. We can't do this
163 // during normal operation, as it will cause race conditions.
164 for (int i = 0; i < event_loop.state->length; ++i) {
165 struct state_item *item = event_loop.state->items[i];
166 if (item->flags == ITEM_IS_FD) {
167 _remove_event(item->inner.fd);
168 } else {
169 _remove_timer(item->inner.timer);
170 }
171 free(item);
172 }
173 event_loop.state->length = 0; // reset state list
136} 174}
137 175
138void init_event_loop() { 176void init_event_loop() {
@@ -141,4 +179,5 @@ void init_event_loop() {
141 event_loop.fds.items = malloc(event_loop.fds.capacity * sizeof(struct pollfd)); 179 event_loop.fds.items = malloc(event_loop.fds.capacity * sizeof(struct pollfd));
142 event_loop.items = create_list(); 180 event_loop.items = create_list();
143 event_loop.timers = create_list(); 181 event_loop.timers = create_list();
182 event_loop.state = create_list();
144} 183}