Browse Source

*** empty log message ***

master
Marc Alexander Lehmann 11 years ago
parent
commit
eef00b16ee
  1. 3
      Changes
  2. 33
      ev_epoll.c
  3. 5
      ev_vars.h
  4. 6
      ev_wrap.h

3
Changes

@ -4,7 +4,10 @@ TODO: move some other examples to common idioms? combining watchers,
thread usage, coroutine switch?
TODO: /dev/null epoll breakage, maybe catch EPERM?
TODO: frankenpoll
4.03
- support files, /dev/zero etc. the same way as select in the epoll
backend, by generating events on our own.
- define EV_READ/EV_WRITE as macros in event.h, as some programs use
#ifdef to test for them.

33
ev_epoll.c

@ -1,7 +1,7 @@
/*
* libev epoll fd activity backend
*
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
@ -53,7 +53,8 @@
* (such as files). while not critical, no other advanced interface
* seems to share this (rather non-unixy) limitation.
* e) epoll claims to be embeddable, but in practise you never get
* a ready event for the epoll fd.
* a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
* f) epoll_ctl returning EPERM means the fd is always ready.
*
* 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
@ -64,6 +65,8 @@
#include <sys/epoll.h>
#define EV_EMASK_EPERM 0x80
static void
epoll_modify (EV_P_ int fd, int oev, int nev)
{
@ -112,6 +115,19 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
return;
}
else if (expect_true (errno == EPERM))
{
anfds [fd].emask = EV_EMASK_EPERM;
/* add fd to epoll_eperms, if not already inside */
if (!(oldmask & EV_EMASK_EPERM))
{
array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2);
epoll_eperms [epoll_epermcnt++] = fd;
}
return;
}
fd_kill (EV_A_ fd);
@ -186,6 +202,18 @@ epoll_poll (EV_P_ ev_tstamp timeout)
epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
}
/* now add events for all fds where epoll fails, while select works... */
for (i = epoll_epermcnt; i--; )
{
int fd = epoll_eperms [i];
unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE);
if (anfds [fd].emask & EV_EMASK_EPERM && events)
fd_event (EV_A_ fd, events);
else
epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
}
}
int inline_size
@ -217,6 +245,7 @@ void inline_size
epoll_destroy (EV_P)
{
ev_free (epoll_events);
array_free (epoll_eperm, EMPTY);
}
void inline_size

5
ev_vars.h

@ -1,7 +1,7 @@
/*
* loop member variable declarations
*
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
@ -102,6 +102,9 @@ VARx(int, pollidxmax)
#if EV_USE_EPOLL || EV_GENWRAP
VARx(struct epoll_event *, epoll_events)
VARx(int, epoll_eventmax)
VARx(int *, epoll_eperms)
VARx(int, epoll_epermcnt)
VARx(int, epoll_epermmax)
#endif
#if EV_USE_KQUEUE || EV_GENWRAP

6
ev_wrap.h

@ -40,6 +40,9 @@
#define pollidxmax ((loop)->pollidxmax)
#define epoll_events ((loop)->epoll_events)
#define epoll_eventmax ((loop)->epoll_eventmax)
#define epoll_eperms ((loop)->epoll_eperms)
#define epoll_epermcnt ((loop)->epoll_epermcnt)
#define epoll_epermmax ((loop)->epoll_epermmax)
#define kqueue_changes ((loop)->kqueue_changes)
#define kqueue_changemax ((loop)->kqueue_changemax)
#define kqueue_changecnt ((loop)->kqueue_changecnt)
@ -132,6 +135,9 @@
#undef pollidxmax
#undef epoll_events
#undef epoll_eventmax
#undef epoll_eperms
#undef epoll_epermcnt
#undef epoll_epermmax
#undef kqueue_changes
#undef kqueue_changemax
#undef kqueue_changecnt

Loading…
Cancel
Save