Annotation of embedaddon/lighttpd/src/fdevent_solaris_port.c, revision 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>