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