Annotation of embedaddon/lighttpd/src/fdevent_libev.c, revision 1.1.1.2

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));
1.1.1.2 ! misho      70:                force_assert(watcher);
1.1       misho      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;
1.1.1.2 ! misho     106:        force_assert(timeout_watcher.timer.repeat);
1.1       misho     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>