Merge pull request #1835 from ascent12/swaybar_status_err

Swaybar fix
This commit is contained in:
Drew DeVault 2018-04-21 14:45:33 +02:00 committed by GitHub
commit ce70b9c45c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 22 deletions

View file

@ -401,24 +401,28 @@ void bar_setup(struct swaybar *bar,
render_all_frames(bar); render_all_frames(bar);
} }
static void display_in(int fd, short mask, void *_bar) { static void display_in(int fd, short mask, void *data) {
struct swaybar *bar = (struct swaybar *)_bar; struct swaybar *bar = data;
if (wl_display_dispatch(bar->display) == -1) { if (wl_display_dispatch(bar->display) == -1) {
bar_teardown(bar); bar_teardown(bar);
exit(0); exit(0);
} }
} }
static void ipc_in(int fd, short mask, void *_bar) { static void ipc_in(int fd, short mask, void *data) {
struct swaybar *bar = (struct swaybar *)_bar; struct swaybar *bar = data;
if (handle_ipc_readable(bar)) { if (handle_ipc_readable(bar)) {
render_all_frames(bar); render_all_frames(bar);
} }
} }
static void status_in(int fd, short mask, void *_bar) { static void status_in(int fd, short mask, void *data) {
struct swaybar *bar = (struct swaybar *)_bar; struct swaybar *bar = data;
if (status_handle_readable(bar->status)) { if (mask & (POLLHUP | POLLERR)) {
status_error(bar->status, "[error reading from status command]");
render_all_frames(bar);
remove_event(fd);
} else if (status_handle_readable(bar->status)) {
render_all_frames(bar); render_all_frames(bar);
} }
} }

View file

@ -72,25 +72,19 @@ void add_event(int fd, short mask,
} }
bool remove_event(int fd) { 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) { for (int i = 0; i < event_loop.fds.length; ++i) {
if (event_loop.fds.items[i].fd == fd) { if (event_loop.fds.items[i].fd == fd) {
index = i; event_loop.fds.items[i].fd = -1;
}
}
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; return true;
} else {
return false;
} }
} }
return false;
}
static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) {
const struct timer_item *timer_item = _timer_item; const struct timer_item *timer_item = _timer_item;
@ -118,11 +112,29 @@ void event_loop_poll() {
struct pollfd pfd = event_loop.fds.items[i]; struct pollfd pfd = event_loop.fds.items[i];
struct event_item *item = (struct event_item *)event_loop.items->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); 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 // check timers
// not tested, but seems to work // not tested, but seems to work
for (int i = 0; i < event_loop.timers->length; ++i) { for (int i = 0; i < event_loop.timers->length; ++i) {