File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / fdevent_solaris_port.c
Revision 1.1.1.2 (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_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));
  161: 	force_assert(NULL != ev->port_events);
  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>