ev_fd_cb cb;
void *data;
+ bool enabled;
struct ev_eloop *loop;
};
for (i = 0; i < count; ++i) {
fd = ep[i].data.ptr;
- if (!fd || !fd->cb)
+ if (!fd || !fd->cb || !fd->enabled)
continue;
mask = 0;
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);
fd->mask = mask;
fd->cb = cb;
fd->data = data;
+ fd->enabled = true;
*out = fd;
return 0;
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;
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,
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;
}
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