[core] fix fd leak when using libev (fixes #2761)

server.event-handler = "libev" would leak fds after the change made
in commit:40f16d5 since fdevent_libev.c:fdevent_libev_poll() always
returned 0 ready events after handling the event callbacks itself.
Therefore, fdevent_libev.c:fdevent_libev_poll() must also call
fdevent_sched_run() to handled fds scheduled to be closed.

This bug was introduced in 1.4.42.

(thx mittwinter for troubleshooting and identifying problem)

Note: server.event-handler = "libev" is no longer recommended.
lighttpd provides event handlers optimized for modern systems for most
platforms, and the limited way that lighttpd uses libev does not provide
any advantages over the OS-specific optimized event handlers.

x-ref:
  "fd leak with libev in 1.4.42"
  https://redmine.lighttpd.net/issues/2761
This commit is contained in:
Glenn Strauss 2016-10-26 16:28:25 -04:00
parent 86c68ecbc7
commit eb37615a47
1 changed files with 5 additions and 2 deletions

View File

@ -12,15 +12,17 @@
static void io_watcher_cb(struct ev_loop *loop, ev_io *w, int revents) {
fdevents *ev = w->data;
fdnode *fdn = ev->fdarray[w->fd];
fdevent_handler handler = fdevent_get_handler(ev, w->fd);
void *context = fdevent_get_context(ev, w->fd);
int r = 0;
UNUSED(loop);
if (NULL == handler) return;
if (revents & EV_READ) r |= FDEVENT_IN;
if (revents & EV_WRITE) r |= FDEVENT_OUT;
if (revents & EV_ERROR) r |= FDEVENT_ERR;
switch (r = (*fdn->handler)(ev->srv, fdn->ctx, r)) {
switch (r = (*handler)(ev->srv, context, r)) {
case HANDLER_FINISHED:
case HANDLER_GO_ON:
case HANDLER_WAIT_FOR_EVENT:
@ -98,6 +100,7 @@ static int fdevent_libev_poll(fdevents *ev, int timeout_ms) {
ev_timer_again(ev->libev_loop, &timeout_watcher);
ev_run(ev->libev_loop, EVRUN_ONCE);
fdevent_sched_run(ev->srv, ev);
return 0;
}