File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / fdevent_poll.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (7 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

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

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