uloop: prevent fd callbacks for unregistered fds by ensuring that pointers in the epoll array are cleared

This commit is contained in:
Felix Fietkau 2012-06-24 21:06:16 +02:00
parent eedf91d212
commit 63bc6593c3

23
uloop.c
View file

@ -201,16 +201,26 @@ static int register_poll(struct uloop_fd *fd, unsigned int flags)
return epoll_ctl(poll_fd, op, fd->fd, &ev); return epoll_ctl(poll_fd, op, fd->fd, &ev);
} }
static int cur_fd, cur_nfds;
static struct epoll_event events[ULOOP_MAX_EVENTS];
int uloop_fd_delete(struct uloop_fd *sock) int uloop_fd_delete(struct uloop_fd *sock)
{ {
int i;
for (i = cur_fd + 1; i < cur_nfds; i++) {
if (events[i].data.ptr != sock)
continue;
events[i].data.ptr = NULL;
}
sock->registered = false; sock->registered = false;
return epoll_ctl(poll_fd, EPOLL_CTL_DEL, sock->fd, 0); return epoll_ctl(poll_fd, EPOLL_CTL_DEL, sock->fd, 0);
} }
static void uloop_run_events(int timeout) static void uloop_run_events(int timeout)
{ {
struct epoll_event events[ULOOP_MAX_EVENTS]; int n, nfds;
int nfds, n;
nfds = epoll_wait(poll_fd, events, ARRAY_SIZE(events), timeout); nfds = epoll_wait(poll_fd, events, ARRAY_SIZE(events), timeout);
for(n = 0; n < nfds; ++n) for(n = 0; n < nfds; ++n)
@ -218,6 +228,9 @@ static void uloop_run_events(int timeout)
struct uloop_fd *u = events[n].data.ptr; struct uloop_fd *u = events[n].data.ptr;
unsigned int ev = 0; unsigned int ev = 0;
if (!u)
continue;
if(events[n].events & EPOLLERR) { if(events[n].events & EPOLLERR) {
u->error = true; u->error = true;
uloop_fd_delete(u); uloop_fd_delete(u);
@ -235,9 +248,13 @@ static void uloop_run_events(int timeout)
if(events[n].events & EPOLLOUT) if(events[n].events & EPOLLOUT)
ev |= ULOOP_WRITE; ev |= ULOOP_WRITE;
if(u->cb) if(u->cb) {
cur_fd = n;
cur_nfds = nfds;
u->cb(u, ev); u->cb(u, ev);
}
} }
cur_nfds = 0;
} }
#endif #endif