• 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 <assert.h>
6
7#ifdef USE_LIBEV
8
9# include <ev.h>
10
11static void io_watcher_cb(struct ev_loop *loop, ev_io *w, int revents) {
12	fdevents *ev = w->data;
13	fdnode *fdn = ev->fdarray[w->fd];
14	int r = 0;
15	UNUSED(loop);
16
17	if (revents & EV_READ) r |= FDEVENT_IN;
18	if (revents & EV_WRITE) r |= FDEVENT_OUT;
19	if (revents & EV_ERROR) r |= FDEVENT_ERR;
20
21	switch (r = (*fdn->handler)(ev->srv, fdn->ctx, r)) {
22	case HANDLER_FINISHED:
23	case HANDLER_GO_ON:
24	case HANDLER_WAIT_FOR_EVENT:
25	case HANDLER_WAIT_FOR_FD:
26		break;
27	case HANDLER_ERROR:
28		/* should never happen */
29		SEGFAULT();
30		break;
31	default:
32		log_error_write(ev->srv, __FILE__, __LINE__, "d", r);
33		break;
34	}
35}
36
37static void fdevent_libev_free(fdevents *ev) {
38	UNUSED(ev);
39}
40
41static int fdevent_libev_event_del(fdevents *ev, int fde_ndx, int fd) {
42	fdnode *fdn;
43	ev_io *watcher;
44
45	if (-1 == fde_ndx) return -1;
46
47	fdn = ev->fdarray[fd];
48	watcher = fdn->handler_ctx;
49
50	if (!watcher) return -1;
51
52	ev_io_stop(ev->libev_loop, watcher);
53	free(watcher);
54	fdn->handler_ctx = NULL;
55
56	return -1;
57}
58
59static int fdevent_libev_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
60	fdnode *fdn = ev->fdarray[fd];
61	ev_io *watcher = fdn->handler_ctx;
62	int ev_events = 0;
63	UNUSED(fde_ndx);
64
65	if (events & FDEVENT_IN)  ev_events |= EV_READ;
66	if (events & FDEVENT_OUT) ev_events |= EV_WRITE;
67
68	if (!watcher) {
69		fdn->handler_ctx = watcher = calloc(1, sizeof(ev_io));
70		force_assert(watcher);
71
72		ev_io_init(watcher, io_watcher_cb, fd, ev_events);
73		watcher->data = ev;
74		ev_io_start(ev->libev_loop, watcher);
75	} else {
76		if ((watcher->events & (EV_READ | EV_WRITE)) != ev_events) {
77			ev_io_stop(ev->libev_loop, watcher);
78			ev_io_set(watcher, watcher->fd, ev_events);
79			ev_io_start(ev->libev_loop, watcher);
80		}
81	}
82
83	return fd;
84}
85
86static void timeout_watcher_cb(struct ev_loop *loop, ev_timer *w, int revents) {
87	UNUSED(loop);
88	UNUSED(w);
89	UNUSED(revents);
90
91	ev_timer_stop(loop, w);
92}
93
94
95static int fdevent_libev_poll(fdevents *ev, int timeout_ms) {
96	union {
97		struct ev_watcher w;
98		struct ev_timer timer;
99	} timeout_watcher;
100
101	if (!timeout_ms) timeout_ms = 1;
102
103	ev_init(&timeout_watcher.w, NULL);
104	ev_set_cb(&timeout_watcher.timer, timeout_watcher_cb);
105	timeout_watcher.timer.repeat = ((ev_tstamp) timeout_ms)/1000.0;
106	force_assert(timeout_watcher.timer.repeat);
107	ev_timer_again(ev->libev_loop, &timeout_watcher.timer);
108
109	ev_loop(ev->libev_loop, EVLOOP_ONESHOT);
110
111	ev_timer_stop(ev->libev_loop, &timeout_watcher.timer);
112
113	return 0;
114}
115
116static int fdevent_libev_event_get_revent(fdevents *ev, size_t ndx) {
117	UNUSED(ev);
118	UNUSED(ndx);
119
120	return 0;
121}
122
123static int fdevent_libev_event_get_fd(fdevents *ev, size_t ndx) {
124	UNUSED(ev);
125	UNUSED(ndx);
126
127	return -1;
128}
129
130static int fdevent_libev_event_next_fdndx(fdevents *ev, int ndx) {
131	UNUSED(ev);
132	UNUSED(ndx);
133
134	return -1;
135}
136
137static int fdevent_libev_reset(fdevents *ev) {
138	UNUSED(ev);
139
140	ev_default_fork();
141
142	return 0;
143}
144
145int fdevent_libev_init(fdevents *ev) {
146	ev->type = FDEVENT_HANDLER_LIBEV;
147#define SET(x) \
148	ev->x = fdevent_libev_##x;
149
150	SET(free);
151	SET(poll);
152	SET(reset);
153
154	SET(event_del);
155	SET(event_set);
156
157	SET(event_next_fdndx);
158	SET(event_get_fd);
159	SET(event_get_revent);
160
161	if (NULL == (ev->libev_loop = ev_default_loop(0))) {
162		log_error_write(ev->srv, __FILE__, __LINE__, "S",
163			"ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
164
165		return -1;
166	}
167
168	return 0;
169}
170
171#else
172int fdevent_libev_init(fdevents *ev) {
173	UNUSED(ev);
174
175	log_error_write(ev->srv, __FILE__, __LINE__, "S",
176		"libev not supported, try to set server.event-handler = \"poll\" or \"select\"");
177
178	return -1;
179}
180#endif
181