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

1.1.1.3 ! misho       1: #include "first.h"
        !             2: 
1.1       misho       3: #include "base.h"
                      4: #include "log.h"
                      5: 
                      6: #include <sys/types.h>
                      7: 
                      8: #include <unistd.h>
                      9: #include <stdlib.h>
                     10: #include <string.h>
                     11: #include <errno.h>
                     12: #include <stdio.h>
                     13: #include <fcntl.h>
                     14: #include <assert.h>
                     15: 
                     16: 
                     17: fdevents *fdevent_init(server *srv, size_t maxfds, fdevent_handler_t type) {
                     18:        fdevents *ev;
                     19: 
                     20:        ev = calloc(1, sizeof(*ev));
1.1.1.3 ! misho      21:        force_assert(NULL != ev);
1.1       misho      22:        ev->srv = srv;
                     23:        ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
1.1.1.3 ! misho      24:        force_assert(NULL != ev->fdarray);
1.1       misho      25:        ev->maxfds = maxfds;
                     26: 
                     27:        switch(type) {
                     28:        case FDEVENT_HANDLER_POLL:
                     29:                if (0 != fdevent_poll_init(ev)) {
1.1.1.2   misho      30:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      31:                                "event-handler poll failed");
1.1.1.2   misho      32:                        goto error;
1.1       misho      33:                }
                     34:                return ev;
                     35:        case FDEVENT_HANDLER_SELECT:
                     36:                if (0 != fdevent_select_init(ev)) {
1.1.1.2   misho      37:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      38:                                "event-handler select failed");
1.1.1.2   misho      39:                        goto error;
1.1       misho      40:                }
                     41:                return ev;
                     42:        case FDEVENT_HANDLER_LINUX_SYSEPOLL:
                     43:                if (0 != fdevent_linux_sysepoll_init(ev)) {
1.1.1.2   misho      44:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      45:                                "event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"");
1.1.1.2   misho      46:                        goto error;
1.1       misho      47:                }
                     48:                return ev;
                     49:        case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
                     50:                if (0 != fdevent_solaris_devpoll_init(ev)) {
1.1.1.2   misho      51:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      52:                                "event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"");
1.1.1.2   misho      53:                        goto error;
1.1       misho      54:                }
                     55:                return ev;
                     56:        case FDEVENT_HANDLER_SOLARIS_PORT:
                     57:                if (0 != fdevent_solaris_port_init(ev)) {
1.1.1.2   misho      58:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      59:                                "event-handler solaris-eventports failed, try to set server.event-handler = \"poll\" or \"select\"");
1.1.1.2   misho      60:                        goto error;
1.1       misho      61:                }
                     62:                return ev;
                     63:        case FDEVENT_HANDLER_FREEBSD_KQUEUE:
                     64:                if (0 != fdevent_freebsd_kqueue_init(ev)) {
1.1.1.2   misho      65:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      66:                                "event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"");
1.1.1.2   misho      67:                        goto error;
1.1       misho      68:                }
                     69:                return ev;
                     70:        case FDEVENT_HANDLER_LIBEV:
                     71:                if (0 != fdevent_libev_init(ev)) {
1.1.1.2   misho      72:                        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      73:                                "event-handler libev failed, try to set server.event-handler = \"poll\" or \"select\"");
1.1.1.2   misho      74:                        goto error;
1.1       misho      75:                }
                     76:                return ev;
                     77:        case FDEVENT_HANDLER_UNSET:
                     78:                break;
                     79:        }
                     80: 
1.1.1.2   misho      81: error:
                     82:        free(ev->fdarray);
                     83:        free(ev);
                     84: 
                     85:        log_error_write(srv, __FILE__, __LINE__, "S",
1.1       misho      86:                "event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"");
                     87:        return NULL;
                     88: }
                     89: 
                     90: void fdevent_free(fdevents *ev) {
                     91:        size_t i;
                     92:        if (!ev) return;
                     93: 
                     94:        if (ev->free) ev->free(ev);
                     95: 
                     96:        for (i = 0; i < ev->maxfds; i++) {
                     97:                if (ev->fdarray[i]) free(ev->fdarray[i]);
                     98:        }
                     99: 
                    100:        free(ev->fdarray);
                    101:        free(ev);
                    102: }
                    103: 
                    104: int fdevent_reset(fdevents *ev) {
                    105:        if (ev->reset) return ev->reset(ev);
                    106: 
                    107:        return 0;
                    108: }
                    109: 
                    110: static fdnode *fdnode_init(void) {
                    111:        fdnode *fdn;
                    112: 
                    113:        fdn = calloc(1, sizeof(*fdn));
1.1.1.3 ! misho     114:        force_assert(NULL != fdn);
1.1       misho     115:        fdn->fd = -1;
                    116:        return fdn;
                    117: }
                    118: 
                    119: static void fdnode_free(fdnode *fdn) {
                    120:        free(fdn);
                    121: }
                    122: 
                    123: int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
                    124:        fdnode *fdn;
                    125: 
                    126:        fdn = fdnode_init();
                    127:        fdn->handler = handler;
                    128:        fdn->fd      = fd;
                    129:        fdn->ctx     = ctx;
                    130:        fdn->handler_ctx = NULL;
                    131:        fdn->events  = 0;
                    132: 
                    133:        ev->fdarray[fd] = fdn;
                    134: 
                    135:        return 0;
                    136: }
                    137: 
                    138: int fdevent_unregister(fdevents *ev, int fd) {
                    139:        fdnode *fdn;
                    140: 
                    141:        if (!ev) return 0;
                    142:        fdn = ev->fdarray[fd];
                    143: 
                    144:        fdnode_free(fdn);
                    145: 
                    146:        ev->fdarray[fd] = NULL;
                    147: 
                    148:        return 0;
                    149: }
                    150: 
1.1.1.3 ! misho     151: void fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
        !           152:        if (-1 == fd) return;
        !           153:        if (NULL == ev->fdarray[fd]) return;
1.1       misho     154: 
1.1.1.3 ! misho     155:        if (ev->event_del) *fde_ndx = ev->event_del(ev, *fde_ndx, fd);
1.1       misho     156:        ev->fdarray[fd]->events = 0;
1.1.1.3 ! misho     157: }
1.1       misho     158: 
1.1.1.3 ! misho     159: void fdevent_event_set(fdevents *ev, int *fde_ndx, int fd, int events) {
        !           160:        if (-1 == fd) return;
1.1       misho     161: 
1.1.1.3 ! misho     162:        /*(Note: skips registering with kernel if initial events is 0,
        !           163:          * so caller should pass non-zero events for initial registration.
        !           164:          * If never registered due to never being called with non-zero events,
        !           165:          * then FDEVENT_HUP or FDEVENT_ERR will never be returned.) */
        !           166:        if (ev->fdarray[fd]->events == events) return;/*(no change; nothing to do)*/
        !           167: 
        !           168:        if (ev->event_set) *fde_ndx = ev->event_set(ev, *fde_ndx, fd, events);
        !           169:        ev->fdarray[fd]->events = events;
1.1       misho     170: }
                    171: 
1.1.1.3 ! misho     172: void fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int event) {
        !           173:        int events;
        !           174:        if (-1 == fd) return;
        !           175: 
        !           176:        events = ev->fdarray[fd]->events;
        !           177:        if ((events & event) || 0 == event) return; /*(no change; nothing to do)*/
1.1       misho     178: 
1.1.1.3 ! misho     179:        events |= event;
        !           180:        if (ev->event_set) *fde_ndx = ev->event_set(ev, *fde_ndx, fd, events);
1.1       misho     181:        ev->fdarray[fd]->events = events;
1.1.1.3 ! misho     182: }
1.1       misho     183: 
1.1.1.3 ! misho     184: void fdevent_event_clr(fdevents *ev, int *fde_ndx, int fd, int event) {
        !           185:        int events;
        !           186:        if (-1 == fd) return;
1.1       misho     187: 
1.1.1.3 ! misho     188:        events = ev->fdarray[fd]->events;
        !           189:        if (!(events & event)) return; /*(no change; nothing to do)*/
        !           190: 
        !           191:        events &= ~event;
        !           192:        if (ev->event_set) *fde_ndx = ev->event_set(ev, *fde_ndx, fd, events);
        !           193:        ev->fdarray[fd]->events = events;
1.1       misho     194: }
                    195: 
                    196: int fdevent_poll(fdevents *ev, int timeout_ms) {
                    197:        if (ev->poll == NULL) SEGFAULT();
                    198:        return ev->poll(ev, timeout_ms);
                    199: }
                    200: 
                    201: int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
                    202:        if (ev->event_get_revent == NULL) SEGFAULT();
                    203: 
                    204:        return ev->event_get_revent(ev, ndx);
                    205: }
                    206: 
                    207: int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
                    208:        if (ev->event_get_fd == NULL) SEGFAULT();
                    209: 
                    210:        return ev->event_get_fd(ev, ndx);
                    211: }
                    212: 
                    213: fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
                    214:        if (ev->fdarray[fd] == NULL) SEGFAULT();
                    215:        if (ev->fdarray[fd]->fd != fd) SEGFAULT();
                    216: 
                    217:        return ev->fdarray[fd]->handler;
                    218: }
                    219: 
                    220: void * fdevent_get_context(fdevents *ev, int fd) {
                    221:        if (ev->fdarray[fd] == NULL) SEGFAULT();
                    222:        if (ev->fdarray[fd]->fd != fd) SEGFAULT();
                    223: 
                    224:        return ev->fdarray[fd]->ctx;
                    225: }
                    226: 
1.1.1.2   misho     227: void fd_close_on_exec(int fd) {
1.1       misho     228: #ifdef FD_CLOEXEC
1.1.1.2   misho     229:        if (fd < 0) return;
                    230:        force_assert(-1 != fcntl(fd, F_SETFD, FD_CLOEXEC));
                    231: #else
                    232:        UNUSED(fd);
1.1       misho     233: #endif
1.1.1.2   misho     234: }
                    235: 
                    236: int fdevent_fcntl_set(fdevents *ev, int fd) {
                    237:        fd_close_on_exec(fd);
1.1       misho     238:        if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
                    239: #ifdef O_NONBLOCK
                    240:        return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
                    241: #else
                    242:        return 0;
                    243: #endif
                    244: }
                    245: 
                    246: 
                    247: int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
                    248:        if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
                    249: 
                    250:        return -1;
                    251: }
                    252: 

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