File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / fdevent_solaris_devpoll.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:20:06 2014 UTC (10 years ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_35p0, v1_4_35, HEAD
lighttpd 1.4.35

    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: 	fd_close_on_exec(ev->devpoll_fd);
  125: 	return 0;
  126: }
  127: int fdevent_solaris_devpoll_init(fdevents *ev) {
  128: 	ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
  129: #define SET(x) \
  130: 	ev->x = fdevent_solaris_devpoll_##x;
  131: 
  132: 	SET(free);
  133: 	SET(poll);
  134: 	SET(reset);
  135: 
  136: 	SET(event_del);
  137: 	SET(event_set);
  138: 
  139: 	SET(event_next_fdndx);
  140: 	SET(event_get_fd);
  141: 	SET(event_get_revent);
  142: 
  143: 	ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
  144: 
  145: 	if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
  146: 		log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
  147: 			"opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
  148: 
  149: 		return -1;
  150: 	}
  151: 
  152: 	/* we just wanted to check if it works */
  153: 	close(ev->devpoll_fd);
  154: 
  155: 	ev->devpoll_fd = -1;
  156: 
  157: 	return 0;
  158: }
  159: 
  160: #else
  161: int fdevent_solaris_devpoll_init(fdevents *ev) {
  162: 	UNUSED(ev);
  163: 
  164: 	log_error_write(ev->srv, __FILE__, __LINE__, "S",
  165: 		"solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
  166: 
  167: 	return -1;
  168: }
  169: #endif

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