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>