diff options
author | root <root> | 2007-10-30 20:59:31 +0000 |
---|---|---|
committer | root <root> | 2007-10-30 20:59:31 +0000 |
commit | cc75a05531d9d05ac14fdaec7960b1c970c87bbb (patch) | |
tree | 61871deaccea619e8b69a3b4495eb7c1f12a8dd2 /ev_epoll.c |
initial roguh cut that doesn't immediately barf
Diffstat (limited to 'ev_epoll.c')
-rw-r--r-- | ev_epoll.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/ev_epoll.c b/ev_epoll.c new file mode 100644 index 0000000..42e4a8b --- /dev/null +++ b/ev_epoll.c @@ -0,0 +1,89 @@ +#include <sys/epoll.h> + +static int epoll_fd = -1; + +static void +epoll_reify_fd (int fd) +{ + ANFD *anfd = anfds + fd; + struct ev_io *w; + + int wev = 0; + + for (w = anfd->head; w; w = w->next) + wev |= w->events; + + if (anfd->wev != wev) + { + int mode = wev ? anfd->wev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD : EPOLL_CTL_DEL; + struct epoll_event ev; + ev.events = wev; + ev.data.fd = fd; + fprintf (stderr, "reify %d,%d,%d m%d (r=%d)\n", fd, anfd->wev, wev, mode,//D + epoll_ctl (epoll_fd, mode, fd, &ev) + );//D + anfd->wev = wev; + } +} + +void epoll_postfork_child (void) +{ + int i; + + epoll_fd = epoll_create (256); + + for (i = 0; i < anfdmax; ++i) + epoll_reify_fd (i); +} + +static void epoll_reify (void) +{ + int i; + for (i = 0; i < fdchangecnt; ++i) + epoll_reify_fd (fdchanges [i]); +} + +static struct epoll_event *events; +static int eventmax; + +static void epoll_poll (ev_tstamp timeout) +{ + int eventcnt = epoll_wait (epoll_fd, events, eventmax, ceil (timeout * 1000.)); + int i; + + if (eventcnt < 0) + return; + + for (i = 0; i < eventcnt; ++i) + fd_event ( + events [i].data.fd, + (events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLPRI) ? EV_WRITE : 0) + | (events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0) + ); + + /* if the receive array was full, increase its size */ + if (eventcnt == eventmax) + { + free (events); + eventmax += eventmax >> 1; + events = malloc (sizeof (struct epoll_event) * eventmax); + } +} + +int epoll_init (int flags) +{ + epoll_fd = epoll_create (256); + + if (epoll_fd < 0) + return 0; + + ev_method = EVMETHOD_EPOLL; + method_fudge = 1e-3; /* needed to compensate fro epoll returning early */ + method_reify = epoll_reify; + method_poll = epoll_poll; + + eventmax = 64; /* intiial number of events receivable per poll */ + events = malloc (sizeof (struct epoll_event) * eventmax); + + return 1; +} |