]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: poll: the I/O handler was called twice for polled I/Os
authorWilly Tarreau <w@1wt.eu>
Thu, 13 Dec 2012 23:17:03 +0000 (00:17 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Dec 2012 23:17:03 +0000 (00:17 +0100)
When a polled I/O event is detected, the event is added to the updates
list and the I/O handler is called. Upon return, if the event handler
did not experience an EAGAIN, the event remains in the updates list so
that it will be processed later. But if the event was already in the
spec list, its state is updated and it will be called again immediately
upon exit, by fd_process_spec_events(), so this creates unfairness
between speculative events and polled events.

So don't call the I/O handler upon I/O detection when the FD already is
in the spec list. The fd events are still updated so that the spec list
is up to date with the possible I/O change.

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

index 5f7b7c3d7bb9fd5349f4d511e4504747057090f4..90efaee054e0b2965880b2aad252bef98263dc58 100644 (file)
@@ -179,6 +179,11 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        if (fdtab[fd].ev & FD_POLL_OUT)
                                fd_ev_set(fd, DIR_WR);
 
+                       if (fdtab[fd].spec_p) {
+                               /* This fd was already scheduled for being called as a speculative I/O */
+                               continue;
+                       }
+
                        /* Save number of updates to detect creation of new FDs. */
                        old_updt = fd_nbupdt;
                        fdtab[fd].iocb(fd);
index 36a7b7f41f94eaaa5019e551e5dbb09502db919c..2142132e21bea4050480a84422b2312a07bb0626 100644 (file)
@@ -158,6 +158,13 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        if (fdtab[fd].ev & FD_POLL_OUT)
                                fd_ev_set(fd, DIR_WR);
 
+                       if (fdtab[fd].spec_p) {
+                               /* This fd was already scheduled for being
+                                * called as a speculative I/O.
+                                */
+                               continue;
+                       }
+
                        fdtab[fd].iocb(fd);
                }
        }
index c09232e4b90b4ef0c465b2b16ed2d9f283f92f31..e3ea4db63cb09e4e5112f5f3239714a4a1e19e66 100644 (file)
@@ -181,6 +181,13 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        if (fdtab[fd].ev & FD_POLL_OUT)
                                fd_ev_set(fd, DIR_WR);
 
+                       if (fdtab[fd].spec_p) {
+                               /* This fd was already scheduled for being
+                                * called as a speculative I/O
+                                */
+                               continue;
+                       }
+
                        fdtab[fd].iocb(fd);
                }
        }
index 48a62da18a17198b57fa5f4c05306b3490320e2d..dba5928c362b312a295be4b8eac800b7551d77cc 100644 (file)
@@ -167,6 +167,13 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                                if (fdtab[fd].ev & FD_POLL_OUT)
                                        fd_ev_set(fd, DIR_WR);
 
+                               if (fdtab[fd].spec_p) {
+                                       /* This fd was already scheduled for being
+                                        * called as a speculative I/O.
+                                        */
+                                       continue;
+                               }
+
                                fdtab[fd].iocb(fd);
                        }
                }