Annotation of embedaddon/lighttpd/src/fdevent_poll.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_POLL
        !            16: 
        !            17: # ifdef HAVE_POLL_H
        !            18: #  include <poll.h>
        !            19: # else
        !            20: #  include <sys/poll.h>
        !            21: # endif
        !            22: 
        !            23: static void fdevent_poll_free(fdevents *ev) {
        !            24:        free(ev->pollfds);
        !            25:        if (ev->unused.ptr) free(ev->unused.ptr);
        !            26: }
        !            27: 
        !            28: static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
        !            29:        if (fde_ndx < 0) return -1;
        !            30: 
        !            31:        if ((size_t)fde_ndx >= ev->used) {
        !            32:                log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
        !            33:                        "del! out of range ", fde_ndx, (int) ev->used);
        !            34:                SEGFAULT();
        !            35:        }
        !            36: 
        !            37:        if (ev->pollfds[fde_ndx].fd == fd) {
        !            38:                size_t k = fde_ndx;
        !            39: 
        !            40:                ev->pollfds[k].fd = -1;
        !            41:                /* ev->pollfds[k].events = 0; */
        !            42:                /* ev->pollfds[k].revents = 0; */
        !            43: 
        !            44:                if (ev->unused.size == 0) {
        !            45:                        ev->unused.size = 16;
        !            46:                        ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
        !            47:                } else if (ev->unused.size == ev->unused.used) {
        !            48:                        ev->unused.size += 16;
        !            49:                        ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
        !            50:                }
        !            51: 
        !            52:                ev->unused.ptr[ev->unused.used++] = k;
        !            53:        } else {
        !            54:                log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
        !            55:                        "del! ", ev->pollfds[fde_ndx].fd, fd);
        !            56: 
        !            57:                SEGFAULT();
        !            58:        }
        !            59: 
        !            60:        return -1;
        !            61: }
        !            62: 
        !            63: #if 0
        !            64: static int fdevent_poll_event_compress(fdevents *ev) {
        !            65:        size_t j;
        !            66: 
        !            67:        if (ev->used == 0) return 0;
        !            68:        if (ev->unused.used != 0) return 0;
        !            69: 
        !            70:        for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
        !            71: 
        !            72:        return 0;
        !            73: }
        !            74: #endif
        !            75: 
        !            76: static int fdevent_poll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
        !            77:        int pevents = 0;
        !            78:        if (events & FDEVENT_IN)  pevents |= POLLIN;
        !            79:        if (events & FDEVENT_OUT) pevents |= POLLOUT;
        !            80: 
        !            81:        /* known index */
        !            82: 
        !            83:        if (fde_ndx != -1) {
        !            84:                if (ev->pollfds[fde_ndx].fd == fd) {
        !            85:                        ev->pollfds[fde_ndx].events = pevents;
        !            86: 
        !            87:                        return fde_ndx;
        !            88:                }
        !            89:                log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
        !            90:                        "set: ", fde_ndx, ev->pollfds[fde_ndx].fd);
        !            91:                SEGFAULT();
        !            92:        }
        !            93: 
        !            94:        if (ev->unused.used > 0) {
        !            95:                int k = ev->unused.ptr[--ev->unused.used];
        !            96: 
        !            97:                ev->pollfds[k].fd = fd;
        !            98:                ev->pollfds[k].events = pevents;
        !            99: 
        !           100:                return k;
        !           101:        } else {
        !           102:                if (ev->size == 0) {
        !           103:                        ev->size = 16;
        !           104:                        ev->pollfds = malloc(sizeof(*ev->pollfds) * ev->size);
        !           105:                } else if (ev->size == ev->used) {
        !           106:                        ev->size += 16;
        !           107:                        ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
        !           108:                }
        !           109: 
        !           110:                ev->pollfds[ev->used].fd = fd;
        !           111:                ev->pollfds[ev->used].events = pevents;
        !           112: 
        !           113:                return ev->used++;
        !           114:        }
        !           115: }
        !           116: 
        !           117: static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
        !           118: #if 0
        !           119:        fdevent_poll_event_compress(ev);
        !           120: #endif
        !           121:        return poll(ev->pollfds, ev->used, timeout_ms);
        !           122: }
        !           123: 
        !           124: static int fdevent_poll_event_get_revent(fdevents *ev, size_t ndx) {
        !           125:        int r, poll_r;
        !           126: 
        !           127:        if (ndx >= ev->used) {
        !           128:                log_error_write(ev->srv, __FILE__, __LINE__, "sii",
        !           129:                        "dying because: event: ", (int) ndx, (int) ev->used);
        !           130: 
        !           131:                SEGFAULT();
        !           132: 
        !           133:                return 0;
        !           134:        }
        !           135: 
        !           136:        if (ev->pollfds[ndx].revents & POLLNVAL) {
        !           137:                /* should never happen */
        !           138:                SEGFAULT();
        !           139:        }
        !           140: 
        !           141:        r = 0;
        !           142:        poll_r = ev->pollfds[ndx].revents;
        !           143: 
        !           144:        /* map POLL* to FDEVEN_*; they are probably the same, but still. */
        !           145: 
        !           146:        if (poll_r & POLLIN) r |= FDEVENT_IN;
        !           147:        if (poll_r & POLLOUT) r |= FDEVENT_OUT;
        !           148:        if (poll_r & POLLERR) r |= FDEVENT_ERR;
        !           149:        if (poll_r & POLLHUP) r |= FDEVENT_HUP;
        !           150:        if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
        !           151:        if (poll_r & POLLPRI) r |= FDEVENT_PRI;
        !           152: 
        !           153:        return r;
        !           154: }
        !           155: 
        !           156: static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
        !           157:        return ev->pollfds[ndx].fd;
        !           158: }
        !           159: 
        !           160: static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
        !           161:        size_t i;
        !           162: 
        !           163:        i = (ndx < 0) ? 0 : ndx + 1;
        !           164:        for (; i < ev->used; i++) {
        !           165:                if (ev->pollfds[i].revents) return i;
        !           166:        }
        !           167: 
        !           168:        return -1;
        !           169: }
        !           170: 
        !           171: int fdevent_poll_init(fdevents *ev) {
        !           172:        ev->type = FDEVENT_HANDLER_POLL;
        !           173: #define SET(x) \
        !           174:        ev->x = fdevent_poll_##x;
        !           175: 
        !           176:        SET(free);
        !           177:        SET(poll);
        !           178: 
        !           179:        SET(event_del);
        !           180:        SET(event_set);
        !           181: 
        !           182:        SET(event_next_fdndx);
        !           183:        SET(event_get_fd);
        !           184:        SET(event_get_revent);
        !           185: 
        !           186:        return 0;
        !           187: }
        !           188: 
        !           189: 
        !           190: 
        !           191: 
        !           192: #else
        !           193: int fdevent_poll_init(fdevents *ev) {
        !           194:        UNUSED(ev);
        !           195: 
        !           196:        log_error_write(srv, __FILE__, __LINE__,
        !           197:                "s", "poll is not supported, try to set server.event-handler = \"select\"");
        !           198: 
        !           199:        return -1;
        !           200: }
        !           201: #endif

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