File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / fdevent_poll.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 10:32:48 2013 UTC (10 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_35p0, v1_4_35, v1_4_33, HEAD
1.4.33

    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>