summaryrefslogtreecommitdiff
path: root/ev_poll.c
diff options
context:
space:
mode:
authorroot <root>2007-11-02 16:54:34 +0000
committerroot <root>2007-11-02 16:54:34 +0000
commit0c513fd963e79da73c7d77018523ac956a5066bd (patch)
tree811c9fc8f69f24915a0aeee5200544a0c9be5bb2 /ev_poll.c
parent6879205607d844eab17dd6c735f8e80bf1490baf (diff)
implement poll method, handle enomem by closing a 'random' fd
Diffstat (limited to 'ev_poll.c')
-rw-r--r--ev_poll.c112
1 files changed, 55 insertions, 57 deletions
diff --git a/ev_poll.c b/ev_poll.c
index 4793212..0af63f3 100644
--- a/ev_poll.c
+++ b/ev_poll.c
@@ -29,82 +29,80 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/epoll.h>
+#include <poll.h>
-static int epoll_fd = -1;
+static struct pollfd *polls;
+static int pollmax, pollcnt;
+static int *pollidxs; /* maps fds into structure indices */
+static int pollidxmax;
static void
-epoll_modify (int fd, int oev, int nev)
+pollidx_init (int *base, int count)
{
- int mode = nev ? oev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD : EPOLL_CTL_DEL;
-
- struct epoll_event ev;
- ev.data.fd = fd;
- ev.events =
- (nev & EV_READ ? EPOLLIN : 0)
- | (nev & EV_WRITE ? EPOLLOUT : 0);
-
- epoll_ctl (epoll_fd, mode, fd, &ev);
+ while (count--)
+ *base++ = -1;
}
static void
-epoll_postfork_child (void)
+poll_modify (int fd, int oev, int nev)
{
- int fd;
+ int idx;
+ array_needsize (pollidxs, pollidxmax, fd + 1, pollidx_init);
- epoll_fd = epoll_create (256);
- fcntl (epoll_fd, F_SETFD, FD_CLOEXEC);
+ idx = pollidxs [fd];
- /* re-register interest in fds */
- for (fd = 0; fd < anfdmax; ++fd)
- if (anfds [fd].events)//D
- epoll_modify (fd, EV_NONE, anfds [fd].events);
-}
+ if (idx < 0) /* need to allocate a new pollfd */
+ {
+ idx = pollcnt++;
+ array_needsize (polls, pollmax, pollcnt, );
+ polls [idx].fd = fd;
+ }
-static struct epoll_event *events;
-static int eventmax;
+ if (nev)
+ polls [idx].events =
+ (nev & EV_READ ? POLLIN : 0)
+ | (nev & EV_WRITE ? POLLOUT : 0);
+ else /* remove pollfd */
+ {
+ if (idx < pollcnt--)
+ {
+ pollidxs [fd] = -1;
+ polls [idx] = polls [pollcnt];
+ pollidxs [polls [idx].fd] = idx;
+ }
+ }
+}
static void
-epoll_poll (ev_tstamp timeout)
+poll_poll (ev_tstamp timeout)
{
- int eventcnt = epoll_wait (epoll_fd, events, eventmax, ceil (timeout * 1000.));
- int i;
-
- if (eventcnt < 0)
- return;
+ int res = poll (polls, pollcnt, ceil (timeout * 1000.));
- for (i = 0; i < eventcnt; ++i)
- fd_event (
- events [i].data.fd,
- (events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
- | (events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0)
- );
-
- /* if the receive array was full, increase its size */
- if (expect_false (eventcnt == eventmax))
+ if (res > 0)
+ {
+ int i;
+
+ for (i = 0; i < pollcnt; ++i)
+ fd_event (
+ polls [i].fd,
+ (polls [i].revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
+ | (polls [i].revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
+ );
+ }
+ else if (res < 0)
{
- free (events);
- eventmax = array_roundsize (events, eventmax << 1);
- events = malloc (sizeof (struct epoll_event) * eventmax);
+ if (errno == EBADF)
+ fd_ebadf ();
+ else if (errno == ENOMEM)
+ fd_enomem ();
}
}
static void
-epoll_init (int flags)
+poll_init (int flags)
{
- epoll_fd = epoll_create (256);
-
- if (epoll_fd < 0)
- return;
-
- fcntl (epoll_fd, F_SETFD, FD_CLOEXEC);
-
- ev_method = EVMETHOD_EPOLL;
- method_fudge = 1e-3; /* needed to compensate for epoll returning early */
- method_modify = epoll_modify;
- method_poll = epoll_poll;
-
- eventmax = 64; /* intiial number of events receivable per poll */
- events = malloc (sizeof (struct epoll_event) * eventmax);
+ ev_method = EVMETHOD_POLL;
+ method_fudge = 1e-3; /* needed to compensate for select returning early, very conservative */
+ method_modify = poll_modify;
+ method_poll = poll_poll;
}
-