diff options
Diffstat (limited to 'src/io-epoll.c')
-rw-r--r-- | src/io-epoll.c | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/src/io-epoll.c b/src/io-epoll.c index 8ac230f..32aa090 100644 --- a/src/io-epoll.c +++ b/src/io-epoll.c @@ -14,7 +14,6 @@ #include <fcntl.h> #include <unistd.h> #include <sys/epoll.h> -#include <sys/socket.h> #include <libtf/io.h> #include <libtf/scheduler.h> @@ -24,71 +23,29 @@ struct tf_poll_data { int num_waiters; }; -struct tf_poll_data *tf_epoll_get_data(void) +static struct tf_poll_data *tf_epoll_get_data(void) { struct tf_scheduler *sched = tf_scheduler_get_current(); TF_BUILD_BUG_ON(sizeof(struct tf_poll_data) > sizeof(sched->poll_data)); return (struct tf_poll_data *) &sched->poll_data; } -static int tf_fd_created(struct tf_fd *fd) +static void tf_epoll_init(void) { struct tf_poll_data *pd = tf_epoll_get_data(); - struct epoll_event ev; - int r; - ev.events = EPOLLIN | EPOLLOUT | EPOLLET; - ev.data.ptr = fd; - r = epoll_ctl(pd->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); - if (unlikely(r < 0)) { - TF_BUG_ON(errno == EEXIST); - r = -errno; - return r; - } - - return 0; -} - -static int tf_fd_destroyed(struct tf_fd *fd) -{ - struct tf_poll_data *pd = tf_epoll_get_data(); - - if (fd->flags & TF_FD_AUTOCLOSE) - return 0; - - epoll_ctl(pd->epoll_fd, EPOLL_CTL_DEL, fd->fd, NULL); - return 0; -} - -static void tf_fd_monitor(struct tf_fd *fd, int events) -{ - struct tf_poll_data *pd = tf_epoll_get_data(); - - TF_BUG_ON(fd->waiting_fiber != NULL); - fd->events = events | EPOLLERR | EPOLLHUP; - fd->waiting_fiber = tf_scheduler_get_current()->active_fiber; - pd->num_waiters++; -} - -static void tf_fd_unmonitor(struct tf_fd *fd) -{ - struct tf_poll_data *pd = tf_epoll_get_data(); - - fd->waiting_fiber = NULL; - fd->events = 0; - pd->num_waiters--; + pd->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + pd->num_waiters = 0; + TF_BUG_ON(pd->epoll_fd < 0); } -void tf_poll_init(void) +static void tf_epoll_close(void) { struct tf_poll_data *pd = tf_epoll_get_data(); - pd->epoll_fd = epoll_create1(EPOLL_CLOEXEC); - pd->num_waiters = 0; - TF_BUG_ON(pd->epoll_fd < 0); + close(pd->epoll_fd); } - -int tf_poll(tf_mtime_diff_t timeout) +static int tf_epoll_poll(tf_mtime_diff_t timeout) { struct tf_poll_data *pd = tf_epoll_get_data(); struct epoll_event events[64]; @@ -116,11 +73,66 @@ int tf_poll(tf_mtime_diff_t timeout) return ret; } -void tf_poll_close(void) +static int tf_epoll_fd_created(struct tf_fd *fd) { struct tf_poll_data *pd = tf_epoll_get_data(); + struct epoll_event ev; + int r; - close(pd->epoll_fd); + ev = (struct epoll_event) { + .events = EPOLLIN | EPOLLOUT | EPOLLET, + .data.ptr = fd, + }; + r = epoll_ctl(pd->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); + if (unlikely(r < 0)) { + TF_BUG_ON(errno == EEXIST); + r = -errno; + return r; + } + + return 0; } -#include "io-unix.c" +static int tf_epoll_fd_destroyed(struct tf_fd *fd) +{ + struct tf_poll_data *pd = tf_epoll_get_data(); + + if (fd->flags & TF_FD_AUTOCLOSE) + return 0; + + epoll_ctl(pd->epoll_fd, EPOLL_CTL_DEL, fd->fd, NULL); + return 0; +} + +static void tf_epoll_fd_monitor(struct tf_fd *fd, int events) +{ + struct tf_poll_data *pd = tf_epoll_get_data(); + + TF_BUG_ON(fd->waiting_fiber != NULL); + fd->events = EPOLLERR | EPOLLHUP; + if (events & TF_POLL_READ) + fd->events |= EPOLLIN; + if (events & TF_POLL_WRITE) + fd->events |= EPOLLOUT; + fd->waiting_fiber = tf_scheduler_get_current()->active_fiber; + pd->num_waiters++; +} + +static void tf_epoll_fd_unmonitor(struct tf_fd *fd) +{ + struct tf_poll_data *pd = tf_epoll_get_data(); + + fd->waiting_fiber = NULL; + fd->events = 0; + pd->num_waiters--; +} + +struct tf_poll_hooks tf_epoll_hooks = { + .init = tf_epoll_init, + .close = tf_epoll_close, + .poll = tf_epoll_poll, + .fd_created = tf_epoll_fd_created, + .fd_destroyed = tf_epoll_fd_destroyed, + .fd_monitor = tf_epoll_fd_monitor, + .fd_unmonitor = tf_epoll_fd_unmonitor, +}; |