Annotation of embedaddon/lighttpd/src/fdevent_linux_sysepoll.c, revision 1.1
1.1 ! misho 1: #include "fdevent.h"
! 2: #include "buffer.h"
! 3: #include "log.h"
! 4:
! 5: #include <sys/types.h>
! 6:
! 7: #include <unistd.h>
! 8: #include <stdlib.h>
! 9: #include <stdio.h>
! 10: #include <string.h>
! 11: #include <errno.h>
! 12: #include <signal.h>
! 13: #include <fcntl.h>
! 14:
! 15: #ifdef USE_LINUX_EPOLL
! 16:
! 17: # include <sys/epoll.h>
! 18:
! 19: static void fdevent_linux_sysepoll_free(fdevents *ev) {
! 20: close(ev->epoll_fd);
! 21: free(ev->epoll_events);
! 22: }
! 23:
! 24: static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
! 25: struct epoll_event ep;
! 26:
! 27: if (fde_ndx < 0) return -1;
! 28:
! 29: memset(&ep, 0, sizeof(ep));
! 30:
! 31: ep.data.fd = fd;
! 32: ep.data.ptr = NULL;
! 33:
! 34: if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
! 35: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 36: "epoll_ctl failed: ", strerror(errno), ", dying");
! 37:
! 38: SEGFAULT();
! 39:
! 40: return 0;
! 41: }
! 42:
! 43:
! 44: return -1;
! 45: }
! 46:
! 47: static int fdevent_linux_sysepoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
! 48: struct epoll_event ep;
! 49: int add = 0;
! 50:
! 51: if (fde_ndx == -1) add = 1;
! 52:
! 53: memset(&ep, 0, sizeof(ep));
! 54:
! 55: ep.events = 0;
! 56:
! 57: if (events & FDEVENT_IN) ep.events |= EPOLLIN;
! 58: if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
! 59:
! 60: /**
! 61: *
! 62: * with EPOLLET we don't get a FDEVENT_HUP
! 63: * if the close is delay after everything has
! 64: * sent.
! 65: *
! 66: */
! 67:
! 68: ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
! 69:
! 70: ep.data.ptr = NULL;
! 71: ep.data.fd = fd;
! 72:
! 73: if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
! 74: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 75: "epoll_ctl failed: ", strerror(errno), ", dying");
! 76:
! 77: SEGFAULT();
! 78:
! 79: return 0;
! 80: }
! 81:
! 82: return fd;
! 83: }
! 84:
! 85: static int fdevent_linux_sysepoll_poll(fdevents *ev, int timeout_ms) {
! 86: return epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
! 87: }
! 88:
! 89: static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
! 90: int events = 0, e;
! 91:
! 92: e = ev->epoll_events[ndx].events;
! 93: if (e & EPOLLIN) events |= FDEVENT_IN;
! 94: if (e & EPOLLOUT) events |= FDEVENT_OUT;
! 95: if (e & EPOLLERR) events |= FDEVENT_ERR;
! 96: if (e & EPOLLHUP) events |= FDEVENT_HUP;
! 97: if (e & EPOLLPRI) events |= FDEVENT_PRI;
! 98:
! 99: return events;
! 100: }
! 101:
! 102: static int fdevent_linux_sysepoll_event_get_fd(fdevents *ev, size_t ndx) {
! 103: # if 0
! 104: log_error_write(ev->srv, __FILE__, __LINE__, "SD, D",
! 105: "fdevent_linux_sysepoll_event_get_fd: ", (int) ndx, ev->epoll_events[ndx].data.fd);
! 106: # endif
! 107:
! 108: return ev->epoll_events[ndx].data.fd;
! 109: }
! 110:
! 111: static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
! 112: size_t i;
! 113:
! 114: UNUSED(ev);
! 115:
! 116: i = (ndx < 0) ? 0 : ndx + 1;
! 117:
! 118: return i;
! 119: }
! 120:
! 121: int fdevent_linux_sysepoll_init(fdevents *ev) {
! 122: ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
! 123: #define SET(x) \
! 124: ev->x = fdevent_linux_sysepoll_##x;
! 125:
! 126: SET(free);
! 127: SET(poll);
! 128:
! 129: SET(event_del);
! 130: SET(event_set);
! 131:
! 132: SET(event_next_fdndx);
! 133: SET(event_get_fd);
! 134: SET(event_get_revent);
! 135:
! 136: if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
! 137: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 138: "epoll_create failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
! 139:
! 140: return -1;
! 141: }
! 142:
! 143: if (-1 == fcntl(ev->epoll_fd, F_SETFD, FD_CLOEXEC)) {
! 144: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 145: "fcntl on epoll-fd failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
! 146:
! 147: close(ev->epoll_fd);
! 148:
! 149: return -1;
! 150: }
! 151:
! 152: ev->epoll_events = malloc(ev->maxfds * sizeof(*ev->epoll_events));
! 153:
! 154: return 0;
! 155: }
! 156:
! 157: #else
! 158: int fdevent_linux_sysepoll_init(fdevents *ev) {
! 159: UNUSED(ev);
! 160:
! 161: log_error_write(ev->srv, __FILE__, __LINE__, "S",
! 162: "linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
! 163:
! 164: return -1;
! 165: }
! 166: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>