]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] sepoll: don't count two events on the same FD.
authorWilly Tarreau <w@1wt.eu>
Sat, 28 Mar 2009 20:10:48 +0000 (21:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 28 Mar 2009 22:42:55 +0000 (23:42 +0100)
sepoll counts the number of speculative events it has processed in
order to remain fair with epoll_wait(). If a same FD is processed
both for read and for write, it is counted twice. Fix this.

src/ev_sepoll.c

index 6a3c45913b6b37ececa27f64ad9cbd4b571daba1..ee6284b07ce638697ec0bbea302d4889b2ea2c36 100644 (file)
@@ -331,6 +331,8 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        status = 0;
        spec_idx = nbspec;
        while (likely(spec_idx > 0)) {
+               int done;
+
                spec_idx--;
                fd = spec_list[spec_idx];
                eo = fd_list[fd].e;  /* save old events */
@@ -355,6 +357,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                                fd, fdtab[fd].ev, fd_list[fd].e, fd_list[fd].s1, spec_idx);
                }
 #endif
+               done = 0;
                fdtab[fd].ev &= FD_POLL_STICKY;
                if ((eo & FD_EV_MASK_R) == FD_EV_SPEC_R) {
                        /* The owner is interested in reading from this FD */
@@ -364,7 +367,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                                if (!fdtab[fd].cb[DIR_RD].f(fd))
                                        fd_list[fd].e ^= (FD_EV_WAIT_R ^ FD_EV_SPEC_R);
                                else
-                                       status++;
+                                       done = 1;
                        }
                }
                else if ((eo & FD_EV_MASK_R) == FD_EV_STOP_R) {
@@ -380,7 +383,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                                if (!fdtab[fd].cb[DIR_WR].f(fd))
                                        fd_list[fd].e ^= (FD_EV_WAIT_W ^ FD_EV_SPEC_W);
                                else
-                                       status++;
+                                       done = 1;
                        }
                }
                else if ((eo & FD_EV_MASK_W) == FD_EV_STOP_W) {
@@ -388,6 +391,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        fd_list[fd].e &= ~FD_EV_MASK_W;
                }
 
+               status += done;
                /* one callback might already have closed the fd by itself */
                if (fdtab[fd].state == FD_STCLOSE)
                        continue;