Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.openwrt.org/project/libubox.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-06-24 23:06:16 +0400
committerFelix Fietkau <nbd@openwrt.org>2012-06-24 23:06:16 +0400
commit63bc6593c37b4757199fb65ec1fb607c5e5190e3 (patch)
treeefa76cc3a16b5c1f895270cbcbdc84317c2fc7e0 /uloop.c
parenteedf91d212caea67920848e1c7e9355173359986 (diff)
uloop: prevent fd callbacks for unregistered fds by ensuring that pointers in the epoll array are cleared
Diffstat (limited to 'uloop.c')
-rw-r--r--uloop.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/uloop.c b/uloop.c
index f226f50..bdda0cf 100644
--- a/uloop.c
+++ b/uloop.c
@@ -201,16 +201,26 @@ static int register_poll(struct uloop_fd *fd, unsigned int flags)
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 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;
return epoll_ctl(poll_fd, EPOLL_CTL_DEL, sock->fd, 0);
}
static void uloop_run_events(int timeout)
{
- struct epoll_event events[ULOOP_MAX_EVENTS];
- int nfds, n;
+ int n, nfds;
nfds = epoll_wait(poll_fd, events, ARRAY_SIZE(events), timeout);
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;
unsigned int ev = 0;
+ if (!u)
+ continue;
+
if(events[n].events & EPOLLERR) {
u->error = true;
uloop_fd_delete(u);
@@ -235,9 +248,13 @@ static void uloop_run_events(int timeout)
if(events[n].events & EPOLLOUT)
ev |= ULOOP_WRITE;
- if(u->cb)
+ if(u->cb) {
+ cur_fd = n;
+ cur_nfds = nfds;
u->cb(u, ev);
+ }
}
+ cur_nfds = 0;
}
#endif