Annotation of embedaddon/lighttpd/src/fdevent_poll.c, revision 1.1.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>