Browse Source

*** empty log message ***

master
Marc Alexander Lehmann 12 years ago
parent
commit
3b62b23b9a
3 changed files with 21 additions and 17 deletions
  1. +2
    -1
      Changes
  2. +1
    -0
      ev.c
  3. +18
    -16
      ev_epoll.c

+ 2
- 1
Changes View File

@ -6,7 +6,8 @@ WISH? monotonic clocks times/GetTickCount for coarse corrections?
backend by assuming the kernel event mask hasn't changed if
ADD fails with EEXIST.
- work around spurious event notification bugs in epoll by using
an 8-bit generation counter.
an 8-bit generation counter. recreate kernel state if we receive
spurious notifications or unwanted events.
- use memset to initialise most arrays now and do away with the
init functions.
- expand time-out strategies into a "Be smart about timeouts" section.


+ 1
- 0
ev.c View File

@ -808,6 +808,7 @@ fd_rearm_all (EV_P)
if (anfds [fd].events)
{
anfds [fd].events = 0;
anfds [fd].emask = 0;
fd_change (EV_A_ fd, EV_IOFDSET | 1);
}
}


+ 18
- 16
ev_epoll.c View File

@ -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 <sys/epoll.h>
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;


Loading…
Cancel
Save