Annotation of embedaddon/lighttpd/src/fdevent_solaris_port.c, revision 1.1.1.1

1.1       misho       1: #include "fdevent.h"
                      2: #include "buffer.h"
                      3: #include "log.h"
                      4: 
                      5: #include <sys/types.h>
                      6: 
                      7: #include <unistd.h>
                      8: #include <stdlib.h>
                      9: #include <stdio.h>
                     10: #include <string.h>
                     11: #include <errno.h>
                     12: #include <signal.h>
                     13: #include <fcntl.h>
                     14: 
                     15: #ifdef USE_SOLARIS_PORT
                     16: 
                     17: static const int SOLARIS_PORT_POLL_READ       = POLLIN;
                     18: static const int SOLARIS_PORT_POLL_WRITE      = POLLOUT;
                     19: static const int SOLARIS_PORT_POLL_READ_WRITE = POLLIN & POLLOUT;
                     20: 
                     21: static int fdevent_solaris_port_event_del(fdevents *ev, int fde_ndx, int fd) {
                     22:        if (fde_ndx < 0) return -1;
                     23: 
                     24:        if (0 != port_dissociate(ev->port_fd, PORT_SOURCE_FD, fd)) {
                     25:                log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
                     26:                        "port_dissociate failed: ", strerror(errno), ", dying");
                     27: 
                     28:                SEGFAULT();
                     29: 
                     30:                return 0;
                     31:        }
                     32: 
                     33:        return -1;
                     34: }
                     35: 
                     36: static int fdevent_solaris_port_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
                     37:        const int* user_data = NULL;
                     38: 
                     39:        if ((events & FDEVENT_IN) && (events & FDEVENT_OUT)) {
                     40:                user_data = &SOLARIS_PORT_POLL_READ_WRITE;
                     41:        } else if (events & FDEVENT_IN) {
                     42:                user_data = &SOLARIS_PORT_POLL_READ;
                     43:        } else if (events & FDEVENT_OUT) {
                     44:                user_data = &SOLARIS_PORT_POLL_WRITE;
                     45:        }
                     46: 
                     47:        if (0 != port_associate(ev->port_fd, PORT_SOURCE_FD, fd, *user_data, (void*) user_data)) {
                     48:                log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
                     49:                        "port_associate failed: ", strerror(errno), ", dying");
                     50: 
                     51:                SEGFAULT();
                     52: 
                     53:                return 0;
                     54:        }
                     55: 
                     56:        return fd;
                     57: }
                     58: 
                     59: static int fdevent_solaris_port_event_get_revent(fdevents *ev, size_t ndx) {
                     60:        int events = 0, e;
                     61: 
                     62:        e = ev->port_events[ndx].portev_events;
                     63:        if (e & POLLIN) events |= FDEVENT_IN;
                     64:        if (e & POLLOUT) events |= FDEVENT_OUT;
                     65:        if (e & POLLERR) events |= FDEVENT_ERR;
                     66:        if (e & POLLHUP) events |= FDEVENT_HUP;
                     67:        if (e & POLLPRI) events |= FDEVENT_PRI;
                     68:        if (e & POLLNVAL) events |= FDEVENT_NVAL;
                     69: 
                     70:        return e;
                     71: }
                     72: 
                     73: static int fdevent_solaris_port_event_get_fd(fdevents *ev, size_t ndx) {
                     74:        return ev->port_events[ndx].portev_object;
                     75: }
                     76: 
                     77: static int fdevent_solaris_port_event_next_fdndx(fdevents *ev, int ndx) {
                     78:        size_t i;
                     79: 
                     80:        UNUSED(ev);
                     81: 
                     82:        i = (ndx < 0) ? 0 : ndx + 1;
                     83: 
                     84:        return i;
                     85: }
                     86: 
                     87: static void fdevent_solaris_port_free(fdevents *ev) {
                     88:        close(ev->port_fd);
                     89:        free(ev->port_events);
                     90: }
                     91: 
                     92: /* if there is any error it will return the return values of port_getn, otherwise it will return number of events **/
                     93: static int fdevent_solaris_port_poll(fdevents *ev, int timeout_ms) {
                     94:        int i = 0;
                     95:        int ret;
                     96:        unsigned int available_events, wait_for_events = 0;
                     97:        const int *user_data;
                     98: 
                     99:        struct timespec  timeout;
                    100: 
                    101:        timeout.tv_sec  = timeout_ms/1000L;
                    102:        timeout.tv_nsec = (timeout_ms % 1000L) * 1000000L;
                    103: 
                    104:        /* get the number of file descriptors with events */
                    105:        if ((ret = port_getn(ev->port_fd, ev->port_events, 0, &wait_for_events, &timeout)) < 0) return ret;
                    106: 
                    107:        /* wait for at least one event */
                    108:        if (0 == wait_for_events) wait_for_events = 1;
                    109: 
                    110:        available_events = wait_for_events;
                    111: 
                    112:        /* get the events of the file descriptors */
                    113:        if ((ret = port_getn(ev->port_fd, ev->port_events, ev->maxfds, &available_events, &timeout)) < 0) {
                    114:                /* if errno == ETIME and available_event == wait_for_events we didn't get any events */
                    115:                /* for other errors we didn't get any events either */
                    116:                if (!(errno == ETIME && wait_for_events != available_events)) return ret;
                    117:        }
                    118: 
                    119:        for (i = 0; i < available_events; ++i) {
                    120:                user_data = (const int *) ev->port_events[i].portev_user;
                    121: 
                    122:                if ((ret = port_associate(ev->port_fd, PORT_SOURCE_FD, ev->port_events[i].portev_object,
                    123:                        *user_data, (void*) user_data)) < 0) {
                    124:                        log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
                    125:                                "port_associate failed: ", strerror(errno), ", dying");
                    126: 
                    127:                        SEGFAULT();
                    128: 
                    129:                        return 0;
                    130:                }
                    131:        }
                    132: 
                    133:        return available_events;
                    134: }
                    135: 
                    136: int fdevent_solaris_port_init(fdevents *ev) {
                    137:        ev->type = FDEVENT_HANDLER_SOLARIS_PORT;
                    138: #define SET(x) \
                    139:        ev->x = fdevent_solaris_port_##x;
                    140: 
                    141:        SET(free);
                    142:        SET(poll);
                    143: 
                    144:        SET(event_del);
                    145:        SET(event_set);
                    146: 
                    147:        SET(event_next_fdndx);
                    148:        SET(event_get_fd);
                    149:        SET(event_get_revent);
                    150: 
                    151:        if ((ev->port_fd = port_create()) < 0) {
                    152:                log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
                    153:                        "port_create() failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
                    154: 
                    155:                return -1;
                    156:        }
                    157: 
                    158:        ev->port_events = malloc(ev->maxfds * sizeof(*ev->port_events));
                    159: 
                    160:        return 0;
                    161: }
                    162: 
                    163: #else
                    164: int fdevent_solaris_port_init(fdevents *ev) {
                    165:        UNUSED(ev);
                    166: 
                    167:        log_error_write(ev->srv, __FILE__, __LINE__, "S",
                    168:                "solaris-eventports not supported, try to set server.event-handler = \"poll\" or \"select\"");
                    169: 
                    170:        return -1;
                    171: }
                    172: #endif

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