Annotation of embedaddon/lighttpd/src/fdevent_linux_sysepoll.c, revision 1.1.1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>