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

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

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