]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] event pollers must not wait if a task exists in the run queue
authorWilly Tarreau <w@1wt.eu>
Fri, 13 Jun 2008 19:06:56 +0000 (21:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Jun 2008 13:05:56 +0000 (15:05 +0200)
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.

src/ev_epoll.c
src/ev_kqueue.c
src/ev_poll.c
src/ev_select.c
src/ev_sepoll.c

index 326d5a42ed0f2691ec93134b032bdd7e2926b4fc..0ce68b05ec473793d49fbf368059e28e313733a5 100644 (file)
@@ -232,7 +232,9 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
                fd_flush_changes();
 
        /* now let's wait for events */
-       if (tv_iseternity(exp))
+       if (run_queue)
+               wait_time = 0;
+       else if (tv_iseternity(exp))
                wait_time = -1;
        else if (tv_isge(&now, exp))
                wait_time = 0;
index 773db74a3bfa8dd13661b2f00330fce24df46cb6..f34cdc3c1bcb33b53fafee5a12990adb0a08b9d0 100644 (file)
@@ -106,7 +106,11 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
        struct timespec timeout, *to_ptr;
 
        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;
 
                if (tv_isge(&now, exp))
index 54cd1389a985c54666b60de1e8298aa004524013..63dce5b26ca9c82bcc7610558546934093ff8833 100644 (file)
@@ -124,7 +124,9 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
        }
       
        /* now let's wait for events */
-       if (tv_iseternity(exp))
+       if (run_queue)
+               wait_time = 0;
+       else if (tv_iseternity(exp))
                wait_time = -1;
        else if (tv_isge(&now, exp))
                wait_time = 0;
index 1b897de2e4deb5a5687633b77c9253762cb77f18..bbbbfe0ccc5f419ca4d1b2ea1cb368d837a559bf 100644 (file)
@@ -89,7 +89,7 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
                
        /* allow select to return immediately when needed */
        delta.tv_sec = delta.tv_usec = 0;
-       if (tv_isset(exp)) {
+       if (!run_queue && tv_isset(exp)) {
                if (tv_islt(&now, exp)) {
                        tv_remain(&now, exp, &delta);
                        /* To avoid eventual select loops due to timer precision */
index 26c5b03ccbb14b74c56b994a4d28fd2a3e6fa1b5..800ac0bab2d763d013a3667dc500b0557a7c381c 100644 (file)
@@ -424,9 +424,10 @@ REGPRM2 static void _do_poll(struct poller *p, struct timeval *exp)
        }
        last_skipped = 0;
 
-       if (nbspec || status) {
+       if (nbspec || status || run_queue) {
                /* 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
                 * the next timeout.
                 */