From 59df43cb12f313828fddd9fa962334543adee20f Mon Sep 17 00:00:00 2001 From: root Date: Mon, 27 Oct 2008 13:39:18 +0000 Subject: *** empty log message *** --- ev_epoll.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'ev_epoll.c') diff --git a/ev_epoll.c b/ev_epoll.c index 4c36cfa..f1e16ab 100644 --- a/ev_epoll.c +++ b/ev_epoll.c @@ -52,19 +52,13 @@ * * lots of "weird code" and complication handling in this file is due * to these design problems with epoll, as we try very hard to avoid - * epoll_ctl syscalls for common usage patterns. + * epoll_ctl syscalls for common usage patterns and handle the breakage + * ensuing from receiving events for closed and otherwise long gone + * file descriptors. */ #include -void inline_size -unsigned_char_init (unsigned char *base, int count) -{ - /* memset might be overkill */ - while (count--) - *base++ = 0; -} - static void epoll_modify (EV_P_ int fd, int oev, int nev) { @@ -138,14 +132,18 @@ epoll_poll (EV_P_ ev_tstamp timeout) { struct epoll_event *ev = epoll_events + i; - int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */ + int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */ + int want = anfds [fd].events; int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); - int want = anfds [fd].events; - if (anfds [fd].egen != (unsigned char)(ev->data.u64 >> 32)) - /*fprintf (stderr, "spurious notification fd %d, %d vs %d\n", fd, (int)(ev->data.u64 >> 32), anfds [fd].egen);*/ - continue; + /* check for spurious notification */ + if (expect_false (anfds [fd].egen != (unsigned char)(ev->data.u64 >> 32))) + { + /* recreate kernel state */ + postfork = 1; + continue; + } if (expect_false (got & ~want)) { @@ -156,7 +154,11 @@ epoll_poll (EV_P_ ev_tstamp timeout) ev->events = (want & EV_READ ? EPOLLIN : 0) | (want & EV_WRITE ? EPOLLOUT : 0); - epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev); + if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) + { + postfork = 1; /* an error occured, recreate kernel state */ + continue; + } } fd_event (EV_A_ fd, got); @@ -185,7 +187,7 @@ epoll_init (EV_P_ int flags) backend_modify = epoll_modify; backend_poll = epoll_poll; - epoll_eventmax = 64; /* intiial number of events receivable per poll */ + epoll_eventmax = 64; /* initial number of events receivable per poll */ epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); return EVBACKEND_EPOLL; -- cgit v1.2.3