diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 0ba8555ff..68ab91ae8 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -131,7 +131,7 @@ enum { CO_FL_CTRL_READY = 0x00000100, /* FD was registered, fd_delete() needed */ CO_FL_XPRT_READY = 0x00000200, /* xprt_start() done, xprt can be used */ - /* unused : 0x00000400 */ + CO_FL_WANT_DRAIN = 0x00000400, /* try to drain pending data when closing */ /* This flag is used by data layers to indicate they had to stop * receiving data because a buffer was full. The connection handler diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 17dad4bda..7c970e2bd 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -174,6 +174,8 @@ static inline void conn_ctrl_init(struct connection *conn) static inline void conn_ctrl_close(struct connection *conn) { if (!conn->xprt && (conn->flags & CO_FL_CTRL_READY)) { + if ((conn->flags & (CO_FL_WANT_DRAIN | CO_FL_SOCK_RD_SH)) == CO_FL_WANT_DRAIN) + conn_ctrl_drain(conn); conn->flags &= ~CO_FL_CTRL_READY; if (conn->ctrl->ctrl_close) conn->ctrl->ctrl_close(conn); diff --git a/src/sock.c b/src/sock.c index d05cf7e69..e546d8f4a 100644 --- a/src/sock.c +++ b/src/sock.c @@ -836,7 +836,7 @@ int sock_drain(struct connection *conn) if (fdtab[fd].state & (FD_POLL_ERR|FD_POLL_HUP)) goto shut; - if (!fd_recv_ready(fd)) + if (!(conn->flags & CO_FL_WANT_DRAIN) && !fd_recv_ready(fd)) return 0; /* no drain function defined, use the generic one */