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

1.1.1.3 ! misho       1: #include "first.h"
        !             2: 
1.1       misho       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));
1.1.1.2   misho      72:                force_assert(watcher);
1.1       misho      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: 
1.1.1.3 ! misho      94: static ev_timer timeout_watcher;
1.1       misho      95: 
                     96: static int fdevent_libev_poll(fdevents *ev, int timeout_ms) {
1.1.1.3 ! misho      97:        timeout_watcher.repeat = (timeout_ms > 0) ? timeout_ms/1000.0 : 0.001;
1.1       misho      98: 
1.1.1.3 ! misho      99:        ev_timer_again(ev->libev_loop, &timeout_watcher);
        !           100:        ev_run(ev->libev_loop, EVRUN_ONCE);
1.1       misho     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) {
1.1.1.3 ! misho     135:        struct ev_timer * const timer = &timeout_watcher;
        !           136: 
1.1       misho     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:        }
1.1.1.3 ! misho     158: 
        !           159:        ev_timer_init(timer, timeout_watcher_cb, 0.0, 1.0);
1.1       misho     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>