]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: polling: do not set speculative events on ERR nor HUP
authorWilly Tarreau <w@1wt.eu>
Thu, 6 Dec 2012 23:09:43 +0000 (00:09 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 6 Dec 2012 23:09:43 +0000 (00:09 +0100)
Errors and Hangups are sticky events, which means that once they're
detected, we never clear them, allowing them to be handled later if
needed.

Till now when an error was reported, it used to register a speculative
I/O event for both recv and send. Since the connection had not requested
such events, it was not able to detect a change and did not clear them,
so the events were called in loops until a timeout caused their owner
task to die.

So this patch does two things :
  - stop registering spec events when no I/O activity was requested,
    so that we don't end up with non-disablable polling state ;

  - keep the sticky polling flags (ERR and HUP) when leaving the
    connection handler so that an error notification doesn't
    magically become a normal recv() or send() report once the
    event is converted to a spec event.

It is normally not needed to make the connection handler emit an
error when it detects POLL_ERR because either a registered data
handler will have done it, or the event will be disabled by the
wake() callback.

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

index e2d75ba7a51e7dbc92029fd344825ea3c4f4dc6c..03a9bb08b4cf0829d5b7a59ff3aa627e65b65da9 100644 (file)
@@ -153,7 +153,7 @@ int conn_fd_handler(int fd)
                conn->flags |= CO_FL_CONNECTED;
 
        /* remove the events before leaving */
-       fdtab[fd].ev &= ~(FD_POLL_IN | FD_POLL_OUT | FD_POLL_HUP | FD_POLL_ERR);
+       fdtab[fd].ev &= FD_POLL_STICKY;
 
        /* commit polling changes */
        conn_cond_update_polling(conn);
index 870da105de38ab9911ca080faf4f987708773e42..2cd596aa39f374c4a0e90d1d8b03da77f9bf4265 100644 (file)
@@ -161,10 +161,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                         * them so that if nothing can be done we don't need
                         * to poll again.
                         */
-                       if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
+                       if (fdtab[fd].ev & FD_POLL_IN)
                                fd_ev_set(fd, DIR_RD);
 
-                       if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR))
+                       if (fdtab[fd].ev & FD_POLL_OUT)
                                fd_ev_set(fd, DIR_WR);
 
                        fdtab[fd].iocb(fd);
index 54c52c2ec1491394e869275aabdd469c83b48948..36a7b7f41f94eaaa5019e551e5dbb09502db919c 100644 (file)
@@ -152,10 +152,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                         * them so that if nothing can be done we don't need
                         * to poll again.
                         */
-                       if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
+                       if (fdtab[fd].ev & FD_POLL_IN)
                                fd_ev_set(fd, DIR_RD);
 
-                       if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR))
+                       if (fdtab[fd].ev & FD_POLL_OUT)
                                fd_ev_set(fd, DIR_WR);
 
                        fdtab[fd].iocb(fd);
index 2ce4815d6eb8d351cc74bd30305a4cf7d7def344..cdc357fbeaa9b7934967447e533fbe76bfa45225 100644 (file)
@@ -166,10 +166,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                         * them so that if nothing can be done we don't need
                         * to poll again.
                         */
-                       if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
+                       if (fdtab[fd].ev & FD_POLL_IN)
                                fd_ev_set(fd, DIR_RD);
 
-                       if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR))
+                       if (fdtab[fd].ev & FD_POLL_OUT)
                                fd_ev_set(fd, DIR_WR);
 
                        fdtab[fd].iocb(fd);
index 0ac74e71d15d3d9a2724c895538f8c092811059d..356eed735fba2685292b6374aa2bed1419fb8aca 100644 (file)
@@ -161,10 +161,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                                 * them so that if nothing can be done we don't need
                                 * to poll again.
                                 */
-                               if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
+                               if (fdtab[fd].ev & FD_POLL_IN)
                                        fd_ev_set(fd, DIR_RD);
 
-                               if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR))
+                               if (fdtab[fd].ev & FD_POLL_OUT)
                                        fd_ev_set(fd, DIR_WR);
 
                                fdtab[fd].iocb(fd);