[BUG] event pollers must not wait if a task exists in the run queue

Under some circumstances, a task may already lie in the run queue
(eg: inter-task wakeup). It is disastrous to wait for an event in
this case because some processing gets delayed.
This commit is contained in:
Willy Tarreau 2008-06-13 21:06:56 +02:00
parent 5c6f58fe87
commit 3a6281199a
5 changed files with 15 additions and 6 deletions

View File

@ -232,7 +232,9 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
fd_flush_changes(); fd_flush_changes();
/* now let's wait for events */ /* now let's wait for events */
if (tv_iseternity(exp)) if (run_queue)
wait_time = 0;
else if (tv_iseternity(exp))
wait_time = -1; wait_time = -1;
else if (tv_isge(&now, exp)) else if (tv_isge(&now, exp))
wait_time = 0; wait_time = 0;

View File

@ -106,7 +106,11 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
struct timespec timeout, *to_ptr; struct timespec timeout, *to_ptr;
to_ptr = NULL; // no timeout to_ptr = NULL; // no timeout
if (tv_isset(exp)) { if (run_queue) {
timeout.tv_sec = timeout.tv_nsec = 0;
to_ptr = &timeout;
}
else if (tv_isset(exp)) {
struct timeval delta; struct timeval delta;
if (tv_isge(&now, exp)) if (tv_isge(&now, exp))

View File

@ -124,7 +124,9 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
} }
/* now let's wait for events */ /* now let's wait for events */
if (tv_iseternity(exp)) if (run_queue)
wait_time = 0;
else if (tv_iseternity(exp))
wait_time = -1; wait_time = -1;
else if (tv_isge(&now, exp)) else if (tv_isge(&now, exp))
wait_time = 0; wait_time = 0;

View File

@ -89,7 +89,7 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
/* allow select to return immediately when needed */ /* allow select to return immediately when needed */
delta.tv_sec = delta.tv_usec = 0; delta.tv_sec = delta.tv_usec = 0;
if (tv_isset(exp)) { if (!run_queue && tv_isset(exp)) {
if (tv_islt(&now, exp)) { if (tv_islt(&now, exp)) {
tv_remain(&now, exp, &delta); tv_remain(&now, exp, &delta);
/* To avoid eventual select loops due to timer precision */ /* To avoid eventual select loops due to timer precision */

View File

@ -424,9 +424,10 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
} }
last_skipped = 0; last_skipped = 0;
if (nbspec || status) { if (nbspec || status || run_queue) {
/* Maybe we have processed some events that we must report, or /* Maybe we have processed some events that we must report, or
* maybe we still have events in the spec list, so we must not * maybe we still have events in the spec list, or there are
* some tasks left pending in the run_queue, so we must not
* wait in epoll() otherwise we will delay their delivery by * wait in epoll() otherwise we will delay their delivery by
* the next timeout. * the next timeout.
*/ */