Annotation of embedaddon/lighttpd/src/fdevent_poll.c, revision 1.1.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_POLL
16:
17: # ifdef HAVE_POLL_H
18: # include <poll.h>
19: # else
20: # include <sys/poll.h>
21: # endif
22:
23: static void fdevent_poll_free(fdevents *ev) {
24: free(ev->pollfds);
25: if (ev->unused.ptr) free(ev->unused.ptr);
26: }
27:
28: static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
29: if (fde_ndx < 0) return -1;
30:
31: if ((size_t)fde_ndx >= ev->used) {
32: log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
33: "del! out of range ", fde_ndx, (int) ev->used);
34: SEGFAULT();
35: }
36:
37: if (ev->pollfds[fde_ndx].fd == fd) {
38: size_t k = fde_ndx;
39:
40: ev->pollfds[k].fd = -1;
41: /* ev->pollfds[k].events = 0; */
42: /* ev->pollfds[k].revents = 0; */
43:
44: if (ev->unused.size == 0) {
45: ev->unused.size = 16;
46: ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
47: } else if (ev->unused.size == ev->unused.used) {
48: ev->unused.size += 16;
49: ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
50: }
51:
52: ev->unused.ptr[ev->unused.used++] = k;
53: } else {
54: log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
55: "del! ", ev->pollfds[fde_ndx].fd, fd);
56:
57: SEGFAULT();
58: }
59:
60: return -1;
61: }
62:
63: #if 0
64: static int fdevent_poll_event_compress(fdevents *ev) {
65: size_t j;
66:
67: if (ev->used == 0) return 0;
68: if (ev->unused.used != 0) return 0;
69:
70: for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
71:
72: return 0;
73: }
74: #endif
75:
76: static int fdevent_poll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
77: int pevents = 0;
78: if (events & FDEVENT_IN) pevents |= POLLIN;
79: if (events & FDEVENT_OUT) pevents |= POLLOUT;
80:
81: /* known index */
82:
83: if (fde_ndx != -1) {
84: if (ev->pollfds[fde_ndx].fd == fd) {
85: ev->pollfds[fde_ndx].events = pevents;
86:
87: return fde_ndx;
88: }
89: log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
90: "set: ", fde_ndx, ev->pollfds[fde_ndx].fd);
91: SEGFAULT();
92: }
93:
94: if (ev->unused.used > 0) {
95: int k = ev->unused.ptr[--ev->unused.used];
96:
97: ev->pollfds[k].fd = fd;
98: ev->pollfds[k].events = pevents;
99:
100: return k;
101: } else {
102: if (ev->size == 0) {
103: ev->size = 16;
104: ev->pollfds = malloc(sizeof(*ev->pollfds) * ev->size);
105: } else if (ev->size == ev->used) {
106: ev->size += 16;
107: ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
108: }
109:
110: ev->pollfds[ev->used].fd = fd;
111: ev->pollfds[ev->used].events = pevents;
112:
113: return ev->used++;
114: }
115: }
116:
117: static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
118: #if 0
119: fdevent_poll_event_compress(ev);
120: #endif
121: return poll(ev->pollfds, ev->used, timeout_ms);
122: }
123:
124: static int fdevent_poll_event_get_revent(fdevents *ev, size_t ndx) {
125: int r, poll_r;
126:
127: if (ndx >= ev->used) {
128: log_error_write(ev->srv, __FILE__, __LINE__, "sii",
129: "dying because: event: ", (int) ndx, (int) ev->used);
130:
131: SEGFAULT();
132:
133: return 0;
134: }
135:
136: if (ev->pollfds[ndx].revents & POLLNVAL) {
137: /* should never happen */
138: SEGFAULT();
139: }
140:
141: r = 0;
142: poll_r = ev->pollfds[ndx].revents;
143:
144: /* map POLL* to FDEVEN_*; they are probably the same, but still. */
145:
146: if (poll_r & POLLIN) r |= FDEVENT_IN;
147: if (poll_r & POLLOUT) r |= FDEVENT_OUT;
148: if (poll_r & POLLERR) r |= FDEVENT_ERR;
149: if (poll_r & POLLHUP) r |= FDEVENT_HUP;
150: if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
151: if (poll_r & POLLPRI) r |= FDEVENT_PRI;
152:
153: return r;
154: }
155:
156: static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
157: return ev->pollfds[ndx].fd;
158: }
159:
160: static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
161: size_t i;
162:
163: i = (ndx < 0) ? 0 : ndx + 1;
164: for (; i < ev->used; i++) {
165: if (ev->pollfds[i].revents) return i;
166: }
167:
168: return -1;
169: }
170:
171: int fdevent_poll_init(fdevents *ev) {
172: ev->type = FDEVENT_HANDLER_POLL;
173: #define SET(x) \
174: ev->x = fdevent_poll_##x;
175:
176: SET(free);
177: SET(poll);
178:
179: SET(event_del);
180: SET(event_set);
181:
182: SET(event_next_fdndx);
183: SET(event_get_fd);
184: SET(event_get_revent);
185:
186: return 0;
187: }
188:
189:
190:
191:
192: #else
193: int fdevent_poll_init(fdevents *ev) {
194: UNUSED(ev);
195:
196: log_error_write(srv, __FILE__, __LINE__,
197: "s", "poll is not supported, try to set server.event-handler = \"select\"");
198:
199: return -1;
200: }
201: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>