[mod_proxy] move data_fastcgi into mod_proxy.c
[lighttpd.git] / src / fdevent_libev.c
blob3716727b884059f848052b6b551a8bfb3398c182
1 #include "first.h"
3 #include <stdlib.h>
5 #include "fdevent.h"
6 #include "buffer.h"
7 #include "log.h"
9 #ifdef USE_LIBEV
11 # include <ev.h>
13 static void io_watcher_cb(struct ev_loop *loop, ev_io *w, int revents) {
14 fdevents *ev = w->data;
15 fdevent_handler handler = fdevent_get_handler(ev, w->fd);
16 void *context = fdevent_get_context(ev, w->fd);
17 int r = 0;
18 UNUSED(loop);
19 if (NULL == handler) return;
21 if (revents & EV_READ) r |= FDEVENT_IN;
22 if (revents & EV_WRITE) r |= FDEVENT_OUT;
23 if (revents & EV_ERROR) r |= FDEVENT_ERR;
25 switch (r = (*handler)(ev->srv, context, r)) {
26 case HANDLER_FINISHED:
27 case HANDLER_GO_ON:
28 case HANDLER_WAIT_FOR_EVENT:
29 case HANDLER_WAIT_FOR_FD:
30 break;
31 case HANDLER_ERROR:
32 /* should never happen */
33 SEGFAULT();
34 break;
35 default:
36 log_error_write(ev->srv, __FILE__, __LINE__, "d", r);
37 break;
41 static void fdevent_libev_free(fdevents *ev) {
42 UNUSED(ev);
45 static int fdevent_libev_event_del(fdevents *ev, int fde_ndx, int fd) {
46 fdnode *fdn;
47 ev_io *watcher;
49 if (-1 == fde_ndx) return -1;
51 fdn = ev->fdarray[fd];
52 watcher = fdn->handler_ctx;
54 if (!watcher) return -1;
56 ev_io_stop(ev->libev_loop, watcher);
57 free(watcher);
58 fdn->handler_ctx = NULL;
60 return -1;
63 static int fdevent_libev_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
64 fdnode *fdn = ev->fdarray[fd];
65 ev_io *watcher = fdn->handler_ctx;
66 int ev_events = 0;
67 UNUSED(fde_ndx);
69 if (events & FDEVENT_IN) ev_events |= EV_READ;
70 if (events & FDEVENT_OUT) ev_events |= EV_WRITE;
72 if (!watcher) {
73 fdn->handler_ctx = watcher = calloc(1, sizeof(ev_io));
74 force_assert(watcher);
76 ev_io_init(watcher, io_watcher_cb, fd, ev_events);
77 watcher->data = ev;
78 ev_io_start(ev->libev_loop, watcher);
79 } else {
80 if ((watcher->events & (EV_READ | EV_WRITE)) != ev_events) {
81 ev_io_stop(ev->libev_loop, watcher);
82 ev_io_set(watcher, watcher->fd, ev_events);
83 ev_io_start(ev->libev_loop, watcher);
87 return fd;
90 static void timeout_watcher_cb(struct ev_loop *loop, ev_timer *w, int revents) {
91 UNUSED(loop);
92 UNUSED(w);
93 UNUSED(revents);
96 static ev_timer timeout_watcher;
98 static int fdevent_libev_poll(fdevents *ev, int timeout_ms) {
99 timeout_watcher.repeat = (timeout_ms > 0) ? timeout_ms/1000.0 : 0.001;
101 ev_timer_again(ev->libev_loop, &timeout_watcher);
102 ev_run(ev->libev_loop, EVRUN_ONCE);
103 fdevent_sched_run(ev->srv, ev);
105 return 0;
108 static int fdevent_libev_event_get_revent(fdevents *ev, size_t ndx) {
109 UNUSED(ev);
110 UNUSED(ndx);
112 return 0;
115 static int fdevent_libev_event_get_fd(fdevents *ev, size_t ndx) {
116 UNUSED(ev);
117 UNUSED(ndx);
119 return -1;
122 static int fdevent_libev_event_next_fdndx(fdevents *ev, int ndx) {
123 UNUSED(ev);
124 UNUSED(ndx);
126 return -1;
129 static int fdevent_libev_reset(fdevents *ev) {
130 UNUSED(ev);
132 ev_default_fork();
134 return 0;
137 int fdevent_libev_init(fdevents *ev) {
138 struct ev_timer * const timer = &timeout_watcher;
139 memset(timer, 0, sizeof(*timer));
141 ev->type = FDEVENT_HANDLER_LIBEV;
142 #define SET(x) \
143 ev->x = fdevent_libev_##x;
145 SET(free);
146 SET(poll);
147 SET(reset);
149 SET(event_del);
150 SET(event_set);
152 SET(event_next_fdndx);
153 SET(event_get_fd);
154 SET(event_get_revent);
156 if (NULL == (ev->libev_loop = ev_default_loop(0))) {
157 log_error_write(ev->srv, __FILE__, __LINE__, "S",
158 "ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
160 return -1;
163 ev_timer_init(timer, timeout_watcher_cb, 0.0, 1.0);
165 return 0;
168 #else
169 int fdevent_libev_init(fdevents *ev) {
170 UNUSED(ev);
172 log_error_write(ev->srv, __FILE__, __LINE__, "S",
173 "libev not supported, try to set server.event-handler = \"poll\" or \"select\"");
175 return -1;
177 #endif