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

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: 
1.1.1.2 ! misho     143:        fd_close_on_exec(ev->epoll_fd);
1.1       misho     144: 
                    145:        ev->epoll_events = malloc(ev->maxfds * sizeof(*ev->epoll_events));
                    146: 
                    147:        return 0;
                    148: }
                    149: 
                    150: #else
                    151: int fdevent_linux_sysepoll_init(fdevents *ev) {
                    152:        UNUSED(ev);
                    153: 
                    154:        log_error_write(ev->srv, __FILE__, __LINE__, "S",
                    155:                "linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
                    156: 
                    157:        return -1;
                    158: }
                    159: #endif

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