File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / fdevent_solaris_devpoll.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (7 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

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

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