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>