Sometimes we'd like to do our best to drain pending data before closing
in order to save the peer from risking to receive an RST on close.
This adds a new connection flag CO_FL_WANT_DRAIN that is used to
trigger a call to conn_ctrl_drain() from conn_ctrl_close(), and the
sock_drain() function ignores fd_recv_ready() if this flag is set,
in order to catch latest data. It's not used for now.
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
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);
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 */