mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-28 16:53:48 +00:00
BUG/MEDIUM: connection: always update connection flags prior to computing polling
stream_int_chk_rcv_conn() did not clear connection flags before updating them. It is unsure whether this could have caused the stalled transfers that have been reported since dev15. In order to avoid such further issues, we now use a simple inline function to do all the job.
This commit is contained in:
parent
b016587068
commit
7d28149e92
@ -114,6 +114,24 @@ void conn_update_data_polling(struct connection *c);
|
||||
*/
|
||||
int conn_local_send_proxy(struct connection *conn, unsigned int flag);
|
||||
|
||||
/* Refresh the connection's polling flags from its file descriptor status.
|
||||
* This should be called at the beginning of a connection handler.
|
||||
*/
|
||||
static inline void conn_refresh_polling_flags(struct connection *conn)
|
||||
{
|
||||
conn->flags &= ~(CO_FL_WAIT_ROOM | CO_FL_WAIT_RD | CO_FL_WAIT_DATA | CO_FL_WAIT_WR);
|
||||
|
||||
if (conn->ctrl) {
|
||||
unsigned int flags = conn->flags & ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA);
|
||||
|
||||
if (fd_ev_is_set(conn->t.sock.fd, DIR_RD))
|
||||
flags |= CO_FL_CURR_RD_ENA;
|
||||
if (fd_ev_is_set(conn->t.sock.fd, DIR_WR))
|
||||
flags |= CO_FL_CURR_WR_ENA;
|
||||
conn->flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* inspects c->flags and returns non-zero if DATA ENA changes from the CURR ENA
|
||||
* or if the WAIT flags are set with their respective ENA flags. Additionally,
|
||||
* non-zero is also returned if an error was reported on the connection. This
|
||||
|
@ -46,18 +46,8 @@ int conn_fd_handler(int fd)
|
||||
if (unlikely(!conn))
|
||||
return 0;
|
||||
|
||||
/* before engaging there, we clear the new WAIT_* flags so that we can
|
||||
* more easily detect an EAGAIN condition from anywhere.
|
||||
*/
|
||||
flags = conn->flags &= ~(CO_FL_WAIT_DATA|CO_FL_WAIT_ROOM|CO_FL_WAIT_RD|CO_FL_WAIT_WR);
|
||||
flags &= ~CO_FL_ERROR; /* ensure to call the wake handler upon error */
|
||||
|
||||
/* adjust current polling status if it has been updated below us */
|
||||
if (fd_ev_is_set(conn->t.sock.fd, DIR_RD))
|
||||
conn->flags |= CO_FL_CURR_RD_ENA;
|
||||
|
||||
if (fd_ev_is_set(conn->t.sock.fd, DIR_WR))
|
||||
conn->flags |= CO_FL_CURR_WR_ENA;
|
||||
conn_refresh_polling_flags(conn);
|
||||
flags = conn->flags & ~CO_FL_ERROR; /* ensure to call the wake handler upon error */
|
||||
|
||||
if (unlikely(conn->flags & CO_FL_ERROR))
|
||||
goto leave;
|
||||
|
@ -765,17 +765,20 @@ static void stream_int_chk_rcv_conn(struct stream_interface *si)
|
||||
if (unlikely(si->state > SI_ST_EST || (ib->flags & CF_SHUTR)))
|
||||
return;
|
||||
|
||||
conn_refresh_polling_flags(si->conn);
|
||||
|
||||
if ((ib->flags & CF_DONT_READ) || channel_full(ib)) {
|
||||
/* stop reading */
|
||||
if (!(ib->flags & CF_DONT_READ)) /* full */
|
||||
si->flags |= SI_FL_WAIT_ROOM;
|
||||
conn_data_stop_recv(si->conn);
|
||||
__conn_data_stop_recv(si->conn);
|
||||
}
|
||||
else {
|
||||
/* (re)start reading */
|
||||
si->flags &= ~SI_FL_WAIT_ROOM;
|
||||
conn_data_want_recv(si->conn);
|
||||
__conn_data_want_recv(si->conn);
|
||||
}
|
||||
conn_cond_update_data_polling(si->conn);
|
||||
}
|
||||
|
||||
|
||||
@ -804,9 +807,8 @@ static void stream_int_chk_snd_conn(struct stream_interface *si)
|
||||
*/
|
||||
if (si->conn->ctrl)
|
||||
fd_want_send(si->conn->t.sock.fd);
|
||||
si->conn->flags &= ~(CO_FL_WAIT_DATA|CO_FL_WAIT_ROOM|CO_FL_WAIT_RD|CO_FL_WAIT_WR);
|
||||
if (fd_ev_is_set(si->conn->t.sock.fd, DIR_WR))
|
||||
si->conn->flags |= CO_FL_CURR_WR_ENA;
|
||||
|
||||
conn_refresh_polling_flags(si->conn);
|
||||
|
||||
if (si_conn_send_loop(si->conn) < 0) {
|
||||
/* Write error on the file descriptor */
|
||||
|
Loading…
Reference in New Issue
Block a user