mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-05 21:11:53 +00:00
BUG/MEDIUM: connection: always disable polling upon error
Commit 0ffde2cc
in 1.5-dev13 tried to always disable polling on file
descriptors when errors were encountered. Unfortunately it did not
always succeed in doing so because it relied on detecting polling
changes to disable it. Let's use a dedicated conn_stop_polling()
function that is inconditionally called upon error instead.
This managed to stop a busy loop observed when a health check makes
use of the send-proxy protocol and fails before the connection can
be established.
This commit is contained in:
parent
f0837b259b
commit
36fb02c526
@ -180,6 +180,17 @@ static inline void conn_cond_update_sock_polling(struct connection *c)
|
||||
conn_update_sock_polling(c);
|
||||
}
|
||||
|
||||
/* Stop all polling on the fd. This might be used when an error is encountered
|
||||
* for example.
|
||||
*/
|
||||
static inline void conn_stop_polling(struct connection *c)
|
||||
{
|
||||
c->flags &= ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA |
|
||||
CO_FL_SOCK_RD_ENA | CO_FL_SOCK_WR_ENA |
|
||||
CO_FL_DATA_RD_ENA | CO_FL_DATA_WR_ENA);
|
||||
fd_stop_both(c->t.sock.fd);
|
||||
}
|
||||
|
||||
/* Automatically update polling on connection <c> depending on the DATA and
|
||||
* SOCK flags, and on whether a handshake is in progress or not. This may be
|
||||
* called at any moment when there is a doubt about the effectiveness of the
|
||||
@ -187,7 +198,9 @@ static inline void conn_cond_update_sock_polling(struct connection *c)
|
||||
*/
|
||||
static inline void conn_cond_update_polling(struct connection *c)
|
||||
{
|
||||
if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
|
||||
if (unlikely(c->flags & CO_FL_ERROR))
|
||||
conn_stop_polling(c);
|
||||
else if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
|
||||
conn_update_data_polling(c);
|
||||
else if ((c->flags & CO_FL_POLL_SOCK) && conn_sock_polling_changes(c))
|
||||
conn_update_sock_polling(c);
|
||||
|
@ -166,14 +166,6 @@ void conn_update_data_polling(struct connection *c)
|
||||
{
|
||||
unsigned int f = c->flags;
|
||||
|
||||
if (unlikely(f & CO_FL_ERROR)) {
|
||||
c->flags &= ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA |
|
||||
CO_FL_SOCK_RD_ENA | CO_FL_SOCK_WR_ENA |
|
||||
CO_FL_DATA_RD_ENA | CO_FL_DATA_WR_ENA);
|
||||
fd_stop_both(c->t.sock.fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* update read status if needed */
|
||||
if (unlikely((f & (CO_FL_DATA_RD_ENA|CO_FL_WAIT_RD)) == (CO_FL_DATA_RD_ENA|CO_FL_WAIT_RD))) {
|
||||
fd_poll_recv(c->t.sock.fd);
|
||||
@ -214,14 +206,6 @@ void conn_update_sock_polling(struct connection *c)
|
||||
{
|
||||
unsigned int f = c->flags;
|
||||
|
||||
if (unlikely(f & CO_FL_ERROR)) {
|
||||
c->flags &= ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA |
|
||||
CO_FL_SOCK_RD_ENA | CO_FL_SOCK_WR_ENA |
|
||||
CO_FL_DATA_RD_ENA | CO_FL_DATA_WR_ENA);
|
||||
fd_stop_both(c->t.sock.fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* update read status if needed */
|
||||
if (unlikely((f & (CO_FL_SOCK_RD_ENA|CO_FL_WAIT_RD)) == (CO_FL_SOCK_RD_ENA|CO_FL_WAIT_RD))) {
|
||||
fd_poll_recv(c->t.sock.fd);
|
||||
|
Loading…
Reference in New Issue
Block a user