summaryrefslogtreecommitdiff
path: root/os/ospoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'os/ospoll.c')
-rw-r--r--os/ospoll.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/os/ospoll.c b/os/ospoll.c
index 3c2b80b39..2996ac7f4 100644
--- a/os/ospoll.c
+++ b/os/ospoll.c
@@ -54,6 +54,7 @@ struct ospollfd {
enum ospoll_trigger trigger;
void (*callback)(int fd, int xevents, void *data);
void *data;
+ struct xorg_list deleted;
};
struct ospoll {
@@ -61,6 +62,7 @@ struct ospoll {
struct ospollfd **fds;
int num;
int size;
+ struct xorg_list deleted;
};
#endif
@@ -115,6 +117,19 @@ ospoll_find(struct ospoll *ospoll, int fd)
return -(lo + 1);
}
+#if EPOLL
+static void
+ospoll_clean_deleted(struct ospoll *ospoll)
+{
+ struct ospollfd *osfd, *tmp;
+
+ xorg_list_for_each_entry_safe(osfd, tmp, &ospoll->deleted, deleted) {
+ xorg_list_del(&osfd->deleted);
+ free(osfd);
+ }
+}
+#endif
+
/* Insert an element into an array
*
* base: base address of array
@@ -160,6 +175,7 @@ ospoll_create(void)
free (ospoll);
return NULL;
}
+ xorg_list_init(&ospoll->deleted);
return ospoll;
#endif
#if POLL
@@ -174,6 +190,7 @@ ospoll_destroy(struct ospoll *ospoll)
if (ospoll) {
assert (ospoll->num == 0);
close(ospoll->epoll_fd);
+ ospoll_clean_deleted(ospoll);
free(ospoll->fds);
free(ospoll);
}
@@ -291,7 +308,9 @@ ospoll_remove(struct ospoll *ospoll, int fd)
array_delete(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos);
ospoll->num--;
- free (osfd);
+ osfd->callback = NULL;
+ osfd->data = NULL;
+ xorg_list_add(&osfd->deleted, &ospoll->deleted);
#endif
#if POLL
array_delete(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos);
@@ -382,8 +401,10 @@ ospoll_wait(struct ospoll *ospoll, int timeout)
if (revents & (~(EPOLLIN|EPOLLOUT)))
xevents |= X_NOTIFY_ERROR;
- osfd->callback(osfd->fd, xevents, osfd->data);
+ if (osfd->callback)
+ osfd->callback(osfd->fd, xevents, osfd->data);
}
+ ospoll_clean_deleted(ospoll);
#endif
#if POLL
nready = xserver_poll(ospoll->fds, ospoll->num, timeout);