Annotation of embedaddon/lighttpd/src/fdevent_solaris_port.c, revision 1.1.1.2
1.1.1.2 ! misho 1: #include "first.h"
! 2:
1.1 misho 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));
1.1.1.2 ! misho 161: force_assert(NULL != ev->port_events);
1.1 misho 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>