Annotation of embedaddon/lighttpd/src/fdevent_solaris_devpoll.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_DEVPOLL
! 16:
! 17: # include <sys/devpoll.h>
! 18:
! 19: static void fdevent_solaris_devpoll_free(fdevents *ev) {
! 20: free(ev->devpollfds);
! 21: close(ev->devpoll_fd);
! 22: }
! 23:
! 24: /* return -1 is fine here */
! 25:
! 26: static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
! 27: struct pollfd pfd;
! 28:
! 29: if (fde_ndx < 0) return -1;
! 30:
! 31: pfd.fd = fd;
! 32: pfd.events = POLLREMOVE;
! 33: pfd.revents = 0;
! 34:
! 35: if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
! 36: log_error_write(ev->srv, __FILE__, __LINE__, "S(D, S)",
! 37: "(del) write failed: ", fd, strerror(errno));
! 38:
! 39: return -1;
! 40: }
! 41:
! 42: return -1;
! 43: }
! 44:
! 45: static int fdevent_solaris_devpoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
! 46: struct pollfd pfd;
! 47: int add = 0;
! 48:
! 49: int pevents = 0;
! 50: if (events & FDEVENT_IN) pevents |= POLLIN;
! 51: if (events & FDEVENT_OUT) pevents |= POLLOUT;
! 52:
! 53: if (fde_ndx == -1) add = 1;
! 54:
! 55: pfd.fd = fd;
! 56: pfd.events = pevents;
! 57: pfd.revents = 0;
! 58:
! 59: if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
! 60: log_error_write(ev->srv, __FILE__, __LINE__, "S(D, S)",
! 61: "(set) write failed: ", fd, strerror(errno));
! 62:
! 63: return -1;
! 64: }
! 65:
! 66: return fd;
! 67: }
! 68:
! 69: static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
! 70: struct dvpoll dopoll;
! 71: int ret;
! 72:
! 73: dopoll.dp_timeout = timeout_ms;
! 74: dopoll.dp_nfds = ev->maxfds - 1;
! 75: dopoll.dp_fds = ev->devpollfds;
! 76:
! 77: ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
! 78:
! 79: return ret;
! 80: }
! 81:
! 82: static int fdevent_solaris_devpoll_event_get_revent(fdevents *ev, size_t ndx) {
! 83: int r, poll_r;
! 84:
! 85: r = 0;
! 86: poll_r = ev->devpollfds[ndx].revents;
! 87:
! 88: /* map POLL* to FDEVEN_*; they are probably the same, but still. */
! 89:
! 90: if (poll_r & POLLIN) r |= FDEVENT_IN;
! 91: if (poll_r & POLLOUT) r |= FDEVENT_OUT;
! 92: if (poll_r & POLLERR) r |= FDEVENT_ERR;
! 93: if (poll_r & POLLHUP) r |= FDEVENT_HUP;
! 94: if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
! 95: if (poll_r & POLLPRI) r |= FDEVENT_PRI;
! 96:
! 97: return r;
! 98: }
! 99:
! 100: static int fdevent_solaris_devpoll_event_get_fd(fdevents *ev, size_t ndx) {
! 101: return ev->devpollfds[ndx].fd;
! 102: }
! 103:
! 104: static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
! 105: size_t i;
! 106:
! 107: UNUSED(ev);
! 108:
! 109: i = (last_ndx < 0) ? 0 : last_ndx + 1;
! 110:
! 111: return i;
! 112: }
! 113:
! 114: int fdevent_solaris_devpoll_reset(fdevents *ev) {
! 115: /* a forked process does only inherit the filedescriptor,
! 116: * but every operation on the device will lead to a EACCES */
! 117: if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
! 118: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 119: "opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
! 120:
! 121: return -1;
! 122: }
! 123:
! 124: if (fcntl(ev->devpoll_fd, F_SETFD, FD_CLOEXEC) < 0) {
! 125: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 126: "fcntl /dev/poll fd failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
! 127:
! 128: close(ev->devpoll_fd);
! 129:
! 130: return -1;
! 131: }
! 132: return 0;
! 133: }
! 134: int fdevent_solaris_devpoll_init(fdevents *ev) {
! 135: ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
! 136: #define SET(x) \
! 137: ev->x = fdevent_solaris_devpoll_##x;
! 138:
! 139: SET(free);
! 140: SET(poll);
! 141: SET(reset);
! 142:
! 143: SET(event_del);
! 144: SET(event_set);
! 145:
! 146: SET(event_next_fdndx);
! 147: SET(event_get_fd);
! 148: SET(event_get_revent);
! 149:
! 150: ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
! 151:
! 152: if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
! 153: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
! 154: "opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
! 155:
! 156: return -1;
! 157: }
! 158:
! 159: /* we just wanted to check if it works */
! 160: close(ev->devpoll_fd);
! 161:
! 162: ev->devpoll_fd = -1;
! 163:
! 164: return 0;
! 165: }
! 166:
! 167: #else
! 168: int fdevent_solaris_devpoll_init(fdevents *ev) {
! 169: UNUSED(ev);
! 170:
! 171: log_error_write(ev->srv, __FILE__, __LINE__, "S",
! 172: "solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
! 173:
! 174: return -1;
! 175: }
! 176: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>