From: David Herrmann Date: Fri, 18 May 2012 15:35:18 +0000 (+0200) Subject: eloop: allow enabling/disabling fd sources X-Git-Tag: kmscon-7~982 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ca31d922b0fe3b4b42c5dcb943fdb6520cd0375;p=platform%2Fupstream%2Fkmscon.git eloop: allow enabling/disabling fd sources We sometimes want to be able to enable/disable an fd-source without allocating memory (for a short period, for instance). Therefore, introduce two new functions to enable and disable an fd source. Signed-off-by: David Herrmann --- diff --git a/src/eloop.c b/src/eloop.c index 6764d32..3bfc4d0 100644 --- a/src/eloop.c +++ b/src/eloop.c @@ -71,6 +71,7 @@ struct ev_fd { ev_fd_cb cb; void *data; + bool enabled; struct ev_eloop *loop; }; @@ -346,7 +347,7 @@ int ev_eloop_dispatch(struct ev_eloop *loop, int timeout) for (i = 0; i < count; ++i) { fd = ep[i].data.ptr; - if (!fd || !fd->cb) + if (!fd || !fd->cb || !fd->enabled) continue; mask = 0; @@ -358,7 +359,7 @@ int ev_eloop_dispatch(struct ev_eloop *loop, int timeout) mask |= EV_ERR; if (ep[i].events & EPOLLHUP) { mask |= EV_HUP; - epoll_ctl(loop->efd, EPOLL_CTL_DEL, fd->fd, NULL); + ev_fd_disable(fd); } fd->cb(fd, mask, fd->data); @@ -506,6 +507,7 @@ int ev_fd_new(struct ev_fd **out, int rfd, int mask, ev_fd_cb cb, void *data) fd->mask = mask; fd->cb = cb; fd->data = data; + fd->enabled = true; *out = fd; return 0; @@ -527,28 +529,44 @@ void ev_fd_unref(struct ev_fd *fd) free(fd); } -bool ev_fd_is_bound(struct ev_fd *fd) +static void fd_epoll_add(struct ev_fd *fd) { - return fd && fd->loop; -} + struct epoll_event ep; + int ret; -void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data) -{ - if (!fd) + if (!fd->loop) return; - fd->cb = cb; - fd->data = data; + memset(&ep, 0, sizeof(ep)); + if (fd->mask & EV_READABLE) + ep.events |= EPOLLIN; + if (fd->mask & EV_WRITEABLE) + ep.events |= EPOLLOUT; + ep.data.ptr = fd; + + ret = epoll_ctl(fd->loop->efd, EPOLL_CTL_ADD, fd->fd, &ep); + if (ret) + log_warning("cannot add fd %d to epoll set (%d): %m", + fd->fd, errno); } -void ev_fd_update(struct ev_fd *fd, int mask) +static void fd_epoll_remove(struct ev_fd *fd) { - struct epoll_event ep; + int ret; - if (!fd) + if (!fd->loop) return; - fd->mask = mask; + ret = epoll_ctl(fd->loop->efd, EPOLL_CTL_DEL, fd->fd, NULL); + if (ret) + log_warning("cannto remote fd %d from epoll set (%d): %m", + fd->fd, errno); +} + +static void fd_epoll_update(struct ev_fd *fd) +{ + struct epoll_event ep; + int ret; if (!fd->loop) return; @@ -560,8 +578,58 @@ void ev_fd_update(struct ev_fd *fd, int mask) ep.events |= EPOLLOUT; ep.data.ptr = fd; - if (epoll_ctl(fd->loop->efd, EPOLL_CTL_MOD, fd->fd, &ep)) - log_warning("cannot update epoll fd (%d): %m", errno); + ret = epoll_ctl(fd->loop->efd, EPOLL_CTL_MOD, fd->fd, &ep); + if (ret) + log_warning("cannot update epoll fd %d (%d): %m", + fd->fd, errno); +} + +void ev_fd_enable(struct ev_fd *fd) +{ + if (!fd || fd->enabled) + return; + + fd->enabled = true; + fd_epoll_add(fd); +} + +void ev_fd_disable(struct ev_fd *fd) +{ + if (!fd || !fd->enabled) + return; + + fd->enabled = false; + fd_epoll_remove(fd); +} + +bool ev_fd_is_enabled(struct ev_fd *fd) +{ + return fd && fd->enabled; +} + +bool ev_fd_is_bound(struct ev_fd *fd) +{ + return fd && fd->loop; +} + +void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data) +{ + if (!fd) + return; + + fd->cb = cb; + fd->data = data; +} + +void ev_fd_update(struct ev_fd *fd, int mask) +{ + if (!fd) + return; + + fd->mask = mask; + if (!fd->enabled) + return; + fd_epoll_update(fd); } int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd, @@ -577,42 +645,25 @@ int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd, if (ret) return ret; - ret = ev_eloop_add_fd(loop, fd); - if (ret) { - ev_fd_unref(fd); - return ret; - } - + ev_eloop_add_fd(loop, fd); ev_fd_unref(fd); + *out = fd; return 0; } int ev_eloop_add_fd(struct ev_eloop *loop, struct ev_fd *fd) { - struct epoll_event ep; - - if (!loop || !fd) + if (!loop || !fd || fd->loop) return -EINVAL; - if (fd->loop) - return -EALREADY; - - memset(&ep, 0, sizeof(ep)); - if (fd->mask & EV_READABLE) - ep.events |= EPOLLIN; - if (fd->mask & EV_WRITEABLE) - ep.events |= EPOLLOUT; - ep.data.ptr = fd; - - if (epoll_ctl(loop->efd, EPOLL_CTL_ADD, fd->fd, &ep) < 0) - return -errno; - fd->loop = loop; - ev_fd_ref(fd); ev_eloop_ref(loop); + if (fd->enabled) + fd_epoll_add(fd); + return 0; } @@ -625,8 +676,8 @@ void ev_eloop_rm_fd(struct ev_fd *fd) return; loop = fd->loop; - - epoll_ctl(loop->efd, EPOLL_CTL_DEL, fd->fd, NULL); + if (fd->enabled) + fd_epoll_remove(fd); /* * If we are currently dispatching events, we need to remove ourself diff --git a/src/eloop.h b/src/eloop.h index 776ec0c..221761b 100644 --- a/src/eloop.h +++ b/src/eloop.h @@ -82,6 +82,9 @@ int ev_fd_new(struct ev_fd **out, int fd, int mask, ev_fd_cb cb, void *data); void ev_fd_ref(struct ev_fd *fd); void ev_fd_unref(struct ev_fd *fd); +void ev_fd_enable(struct ev_fd *fd); +void ev_fd_disable(struct ev_fd *fd); +bool ev_fd_is_enabled(struct ev_fd *fd); bool ev_fd_is_bound(struct ev_fd *fd); void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data); void ev_fd_update(struct ev_fd *fd, int mask);