Forums » Development »
[Solved] Using select as event handler makes lighttpd enter in a dangerous loop.
Added by Anonymous over 15 years ago
Hi guys.
I'm using lighttpd 1.5 from svn, and on my environment I don't have any other handler than selec().
I've observed that, after the first event, the select() function apparently isn't cleared, it is locked in '1'.
This makes the main loop at server.c believes that there is an event to be handled.
n = fdevent_poll(srv->ev, 1000); //here we call select(), and it is returning always '1' (...) if (n > 0) { // We don't need to enter here if we don't have a new event. /* n is the number of events */ size_t i; fdevent_get_revents(srv->ev, n, revents); /* handle client connections first * * this is a bit of a hack, but we have to make sure than we handle * close-events before the connection is reused for a keep-alive * request * * this is mostly an issue for mod_proxy_core, but you never know * */ for (i = 0; i < revents->used; i++) { fdevent_revent *revent = revents->ptr[i]; handler_t r; /* skip server-fds */ if (revent->handler == network_server_handle_fdevent) continue; switch (r = (*(revent->handler))(srv, revent->context, revent->revents)) { case HANDLER_WAIT_FOR_FD: server_out_of_fds(srv, NULL); case HANDLER_FINISHED: case HANDLER_GO_ON: case HANDLER_WAIT_FOR_EVENT: break; case HANDLER_ERROR: /* should never happen */ SEGFAULT("got HANDLER_ERROR from a plugin: %s", "dieing"); break; default: ERROR("got handler_t(%d) from a plugin: ignored", r); break; } } for (i = 0; i < revents->used; i++) { fdevent_revent *revent = revents->ptr[i]; handler_t r; /* server fds only */ if (revent->handler != network_server_handle_fdevent) continue;
Someone is facing this problem?
Shall i submit a defect for this? Or I'm missing something?
Replies (5)
RE: Using select as event handler makes lighttpd enter in a dangerous loop. - Added by stbuehler over 15 years ago
I had a look at the code and i couldn't find any evidence for the things you claim.
RE: Using select as event handler makes lighttpd enter in a dangerous loop. - Added by Anonymous over 15 years ago
Hi, sorry for take so long to answer to you.
I've added these two debug printf's to find this issue:
n = fdevent_poll(srv->ev, 1000);
fprintf(stderr, "MENONC - server.c - fdevent_poll(srv->ev, 1000) %d, should be? \n",n);
(...)
if (n > 0) { // We don't need to enter here if we don't have a new event.
/* n is the number of events */
fprintf(stderr, "MENONC - server.c - n %d \n",n);
size_t i;
fdevent_get_revents(srv->ev, n, revents);
(...)
When running, I was able to see fdevent_poll(srv->ev,1000) 0 at every ~1 second.
Then, after the first event coming to lighty, the fdevent_poll function returns always 1, thousands and thousands of "MENONC - server.c - n 1" are displayed on stderr.
I believe that this means that the select functions isn't being cleared correctly, and at every cycle it "have" a event to respond.
The "1000" that I'm passing to select function will make the select wait for, at most, 1s for an event, so if no events are comming, we should see at stderr something like this:
MENONC - server.c - fdevent_poll(srv->ev, 1000) 0, should be?
(1s)
MENONC - server.c - fdevent_poll(srv->ev, 1000) 0, should be?
(1s)
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //we have an event!
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 0, should be? //done with that event.
(1s)
MENONC - server.c - fdevent_poll(srv->ev, 1000) 0, should be?
(1s)
But this is what I'm seeing:
MENONC - server.c - fdevent_poll(srv->ev, 1000) 0, should be?
(1s)
MENONC - server.c - fdevent_poll(srv->ev, 1000) 0, should be?
(1s)
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //we have an event!
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //no events posted
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //no events posted
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //no events posted
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //no events posted
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //no events posted
MENONC - server.c - n 1
MENONC - server.c - fdevent_poll(srv->ev, 1000) 1, should be? //no events posted
MENONC - server.c - n 1
(...)
I hope it helps to find some issue.
Since I was not able to fix it here, I'm trying to use a wrapper to emulates the poll() using select(). Yeah, this is ugly, but at least is working (partially :( )
RE: Using select as event handler makes lighttpd enter in a dangerous loop. - Added by stbuehler over 15 years ago
Did you actually look at the fdevent select code? Did you try to use strace/ktrace/whatever?
RE: Using select as event handler makes lighttpd enter in a dangerous loop. - Added by Anonymous over 15 years ago
I don't have a way to enable any kind of trace on my environment.
If I found some time here, I will try it on a linux or bsd box to provide the logs.
RE: Using select as event handler makes lighttpd enter in a dangerous loop. - Added by stbuehler over 15 years ago
See http://redmine.lighttpd.net/boards/3/topics/2391 and r2705 - I guess that fixes your problem too.