diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-11-25 15:11:20 +0200 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-11-25 15:11:20 +0200 |
commit | 2b19cc385163a43b1d559074a795a8aaab751185 (patch) | |
tree | 322473e3446153c1bbaac8d6d990734b09d15977 /src/io-epoll.c | |
parent | fc1044daf51f32b9d85f8497e4e0bd5a3c1e7fe9 (diff) | |
download | libtf-2b19cc385163a43b1d559074a795a8aaab751185.tar.bz2 libtf-2b19cc385163a43b1d559074a795a8aaab751185.tar.xz |
libtf: implement basic networking i/o
pretty much untested. also some slight changes to how scheduler is
invoked.
Diffstat (limited to 'src/io-epoll.c')
-rw-r--r-- | src/io-epoll.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/io-epoll.c b/src/io-epoll.c index 56d0743..5e28de8 100644 --- a/src/io-epoll.c +++ b/src/io-epoll.c @@ -14,15 +14,12 @@ #include <fcntl.h> #include <unistd.h> #include <sys/epoll.h> +#include <sys/socket.h> #include <libtf/io.h> #include <libtf/fiber.h> -#define TF_FD_AUTOCLOSE 1 -#define TF_FD_RESTORE_BLOCKING 2 -#define TF_FD_STREAM_ORIENTED 4 - -static int tf_fd_init(struct tf_fd *fd, int kfd, int flags) +static int tf_fd_created(struct tf_fd *fd) { struct tf_poll_data *pd = &tf_get_scheduler()->poll_data; struct epoll_event ev; @@ -30,20 +27,28 @@ static int tf_fd_init(struct tf_fd *fd, int kfd, int flags) ev.events = EPOLLIN | EPOLLOUT | EPOLLET; ev.data.ptr = fd; - r = epoll_ctl(pd->epoll_fd, EPOLL_CTL_ADD, kfd, &ev); - if (r < 0) { + r = epoll_ctl(pd->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); + if (unlikely(r < 0)) { TF_BUG_ON(errno == EEXIST); - return -errno; + r = -errno; + return r; } - fd->fd = kfd; - fd->flags = flags; - fd->waiting_fiber = NULL; + return 0; +} +static int tf_fd_destroyed(struct tf_fd *fd) +{ + struct tf_poll_data *pd = &tf_get_scheduler()->poll_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_wait(struct tf_fd *fd, int events) +static void tf_fd_monitor(struct tf_fd *fd, int events) { struct tf_poll_data *pd = &tf_get_scheduler()->poll_data; @@ -53,7 +58,7 @@ static void tf_fd_wait(struct tf_fd *fd, int events) pd->num_waiters++; } -static void tf_fd_release(struct tf_fd *fd) +static void tf_fd_unmonitor(struct tf_fd *fd) { struct tf_poll_data *pd = &tf_get_scheduler()->poll_data; @@ -76,21 +81,23 @@ int tf_poll(tf_mtime_diff_t timeout) struct tf_poll_data *pd = &tf_get_scheduler()->poll_data; struct epoll_event events[64]; struct tf_fd *fd; - int ret = (timeout == 0) ? TF_WAKEUP_TIMEOUT : TF_WAKEUP_FD; - int r, i; + int r, i, ret; if (timeout == 0 && pd->num_waiters == 0) - return ret; + return TF_WAKEUP_TIMEOUT; + ret = TF_WAKEUP_TIMEOUT; do { r = epoll_wait(pd->epoll_fd, events, array_size(events), timeout); + if (r == 0) + break; + for (i = 0; i < r; i++) { fd = (struct tf_fd *) events[i].data.ptr; if (likely(fd->events & events[i].events)) tf_wakeup(fd->waiting_fiber, TF_WAKEUP_FD); } - if (timeout != 0) - ret = TF_WAKEUP_FD; + ret = TF_WAKEUP_FD; timeout = 0; } while (unlikely(r == array_size(events))); |