File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / fdevent_libev.c
Revision 1.1.1.3 (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 <assert.h>
    8: 
    9: #ifdef USE_LIBEV
   10: 
   11: # include <ev.h>
   12: 
   13: static void io_watcher_cb(struct ev_loop *loop, ev_io *w, int revents) {
   14: 	fdevents *ev = w->data;
   15: 	fdnode *fdn = ev->fdarray[w->fd];
   16: 	int r = 0;
   17: 	UNUSED(loop);
   18: 
   19: 	if (revents & EV_READ) r |= FDEVENT_IN;
   20: 	if (revents & EV_WRITE) r |= FDEVENT_OUT;
   21: 	if (revents & EV_ERROR) r |= FDEVENT_ERR;
   22: 
   23: 	switch (r = (*fdn->handler)(ev->srv, fdn->ctx, r)) {
   24: 	case HANDLER_FINISHED:
   25: 	case HANDLER_GO_ON:
   26: 	case HANDLER_WAIT_FOR_EVENT:
   27: 	case HANDLER_WAIT_FOR_FD:
   28: 		break;
   29: 	case HANDLER_ERROR:
   30: 		/* should never happen */
   31: 		SEGFAULT();
   32: 		break;
   33: 	default:
   34: 		log_error_write(ev->srv, __FILE__, __LINE__, "d", r);
   35: 		break;
   36: 	}
   37: }
   38: 
   39: static void fdevent_libev_free(fdevents *ev) {
   40: 	UNUSED(ev);
   41: }
   42: 
   43: static int fdevent_libev_event_del(fdevents *ev, int fde_ndx, int fd) {
   44: 	fdnode *fdn;
   45: 	ev_io *watcher;
   46: 
   47: 	if (-1 == fde_ndx) return -1;
   48: 
   49: 	fdn = ev->fdarray[fd];
   50: 	watcher = fdn->handler_ctx;
   51: 
   52: 	if (!watcher) return -1;
   53: 
   54: 	ev_io_stop(ev->libev_loop, watcher);
   55: 	free(watcher);
   56: 	fdn->handler_ctx = NULL;
   57: 
   58: 	return -1;
   59: }
   60: 
   61: static int fdevent_libev_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
   62: 	fdnode *fdn = ev->fdarray[fd];
   63: 	ev_io *watcher = fdn->handler_ctx;
   64: 	int ev_events = 0;
   65: 	UNUSED(fde_ndx);
   66: 
   67: 	if (events & FDEVENT_IN)  ev_events |= EV_READ;
   68: 	if (events & FDEVENT_OUT) ev_events |= EV_WRITE;
   69: 
   70: 	if (!watcher) {
   71: 		fdn->handler_ctx = watcher = calloc(1, sizeof(ev_io));
   72: 		force_assert(watcher);
   73: 
   74: 		ev_io_init(watcher, io_watcher_cb, fd, ev_events);
   75: 		watcher->data = ev;
   76: 		ev_io_start(ev->libev_loop, watcher);
   77: 	} else {
   78: 		if ((watcher->events & (EV_READ | EV_WRITE)) != ev_events) {
   79: 			ev_io_stop(ev->libev_loop, watcher);
   80: 			ev_io_set(watcher, watcher->fd, ev_events);
   81: 			ev_io_start(ev->libev_loop, watcher);
   82: 		}
   83: 	}
   84: 
   85: 	return fd;
   86: }
   87: 
   88: static void timeout_watcher_cb(struct ev_loop *loop, ev_timer *w, int revents) {
   89: 	UNUSED(loop);
   90: 	UNUSED(w);
   91: 	UNUSED(revents);
   92: }
   93: 
   94: static ev_timer timeout_watcher;
   95: 
   96: static int fdevent_libev_poll(fdevents *ev, int timeout_ms) {
   97: 	timeout_watcher.repeat = (timeout_ms > 0) ? timeout_ms/1000.0 : 0.001;
   98: 
   99: 	ev_timer_again(ev->libev_loop, &timeout_watcher);
  100: 	ev_run(ev->libev_loop, EVRUN_ONCE);
  101: 
  102: 	return 0;
  103: }
  104: 
  105: static int fdevent_libev_event_get_revent(fdevents *ev, size_t ndx) {
  106: 	UNUSED(ev);
  107: 	UNUSED(ndx);
  108: 
  109: 	return 0;
  110: }
  111: 
  112: static int fdevent_libev_event_get_fd(fdevents *ev, size_t ndx) {
  113: 	UNUSED(ev);
  114: 	UNUSED(ndx);
  115: 
  116: 	return -1;
  117: }
  118: 
  119: static int fdevent_libev_event_next_fdndx(fdevents *ev, int ndx) {
  120: 	UNUSED(ev);
  121: 	UNUSED(ndx);
  122: 
  123: 	return -1;
  124: }
  125: 
  126: static int fdevent_libev_reset(fdevents *ev) {
  127: 	UNUSED(ev);
  128: 
  129: 	ev_default_fork();
  130: 
  131: 	return 0;
  132: }
  133: 
  134: int fdevent_libev_init(fdevents *ev) {
  135: 	struct ev_timer * const timer = &timeout_watcher;
  136: 
  137: 	ev->type = FDEVENT_HANDLER_LIBEV;
  138: #define SET(x) \
  139: 	ev->x = fdevent_libev_##x;
  140: 
  141: 	SET(free);
  142: 	SET(poll);
  143: 	SET(reset);
  144: 
  145: 	SET(event_del);
  146: 	SET(event_set);
  147: 
  148: 	SET(event_next_fdndx);
  149: 	SET(event_get_fd);
  150: 	SET(event_get_revent);
  151: 
  152: 	if (NULL == (ev->libev_loop = ev_default_loop(0))) {
  153: 		log_error_write(ev->srv, __FILE__, __LINE__, "S",
  154: 			"ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
  155: 
  156: 		return -1;
  157: 	}
  158: 
  159: 	ev_timer_init(timer, timeout_watcher_cb, 0.0, 1.0);
  160: 
  161: 	return 0;
  162: }
  163: 
  164: #else
  165: int fdevent_libev_init(fdevents *ev) {
  166: 	UNUSED(ev);
  167: 
  168: 	log_error_write(ev->srv, __FILE__, __LINE__, "S",
  169: 		"libev not supported, try to set server.event-handler = \"poll\" or \"select\"");
  170: 
  171: 	return -1;
  172: }
  173: #endif

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