• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/lighttpd-1.4.39/src/
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
23static void fdevent_poll_free(fdevents *ev) {
24	free(ev->pollfds);
25	if (ev->unused.ptr) free(ev->unused.ptr);
26}
27
28static 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
64static 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
76static 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
117static 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
124static 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
156static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
157	return ev->pollfds[ndx].fd;
158}
159
160static 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
171int 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
193int 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
202