mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-13 23:14:46 +00:00
MEDIUM: connection: provide a common conn_full_close() function
Several places got the connection close sequence wrong because it was not obvious. In practice we always need the same sequence when aborting, so let's have a common function for this.
This commit is contained in:
parent
db3b4a2891
commit
2b199c9ac3
@ -26,6 +26,7 @@
|
||||
#include <common/memory.h>
|
||||
#include <types/connection.h>
|
||||
#include <types/listener.h>
|
||||
#include <proto/fd.h>
|
||||
#include <proto/obj_type.h>
|
||||
|
||||
extern struct pool_head *pool2_connection;
|
||||
@ -66,6 +67,23 @@ static inline void conn_xprt_close(struct connection *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* If the connection still has a transport layer, then call its close() function
|
||||
* if any, and delete the file descriptor if a control layer is set. This is
|
||||
* used to close everything at once and atomically. However this is not done if
|
||||
* the CO_FL_XPRT_TRACKED flag is set, which allows logs to take data from the
|
||||
* transport layer very late if needed.
|
||||
*/
|
||||
static inline void conn_full_close(struct connection *conn)
|
||||
{
|
||||
if (conn->xprt && !(conn->flags & CO_FL_XPRT_TRACKED)) {
|
||||
if (conn->xprt->close)
|
||||
conn->xprt->close(conn);
|
||||
if (conn->ctrl)
|
||||
fd_delete(conn->t.sock.fd);
|
||||
conn->xprt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update polling on connection <c>'s file descriptor depending on its current
|
||||
* state as reported in the connection's CO_FL_CURR_* flags, reports of EAGAIN
|
||||
* in CO_FL_WAIT_*, and the sock layer expectations indicated by CO_FL_SOCK_*.
|
||||
|
13
src/checks.c
13
src/checks.c
@ -1184,12 +1184,8 @@ static int wake_srv_chk(struct connection *conn)
|
||||
if (unlikely(conn->flags & CO_FL_ERROR))
|
||||
task_wakeup(s->check.task, TASK_WOKEN_IO);
|
||||
|
||||
if (s->result & (SRV_CHK_FAILED|SRV_CHK_PASSED)) {
|
||||
conn_xprt_close(conn);
|
||||
if (conn->ctrl)
|
||||
fd_delete(conn->t.sock.fd);
|
||||
conn->ctrl = NULL;
|
||||
}
|
||||
if (s->result & (SRV_CHK_FAILED|SRV_CHK_PASSED))
|
||||
conn_full_close(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1387,10 +1383,7 @@ static struct task *process_chk(struct task *t)
|
||||
/* the check expired and the connection was not
|
||||
* yet closed, start by doing this.
|
||||
*/
|
||||
conn_xprt_close(conn);
|
||||
if (conn->ctrl)
|
||||
fd_delete(conn->t.sock.fd);
|
||||
conn->ctrl = NULL;
|
||||
conn_full_close(conn);
|
||||
}
|
||||
|
||||
if ((conn->flags & (CO_FL_CONNECTED|CO_FL_WAIT_L4_CONN)) == CO_FL_WAIT_L4_CONN) {
|
||||
|
@ -249,7 +249,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
||||
static void kill_mini_session(struct session *s)
|
||||
{
|
||||
/* kill the connection now */
|
||||
conn_xprt_close(s->si[0].conn);
|
||||
conn_full_close(s->si[0].conn);
|
||||
|
||||
s->fe->feconn--;
|
||||
if (s->stkctr1_entry || s->stkctr2_entry)
|
||||
@ -273,11 +273,6 @@ static void kill_mini_session(struct session *s)
|
||||
task_delete(s->task);
|
||||
task_free(s->task);
|
||||
|
||||
if (fdtab[s->si[0].conn->t.sock.fd].owner)
|
||||
fd_delete(s->si[0].conn->t.sock.fd);
|
||||
else
|
||||
close(s->si[0].conn->t.sock.fd);
|
||||
|
||||
pool_free2(pool2_connection, s->si[1].conn);
|
||||
pool_free2(pool2_connection, s->si[0].conn);
|
||||
pool_free2(pool2_session, s);
|
||||
|
@ -227,9 +227,7 @@ int stream_int_shutr(struct stream_interface *si)
|
||||
return 0;
|
||||
|
||||
if (si->ob->flags & CF_SHUTW) {
|
||||
conn_xprt_close(si->conn);
|
||||
if (conn->ctrl)
|
||||
fd_delete(si->conn->t.sock.fd);
|
||||
conn_full_close(si->conn);
|
||||
si->state = SI_ST_DIS;
|
||||
si->exp = TICK_ETERNITY;
|
||||
|
||||
@ -318,9 +316,7 @@ int stream_int_shutw(struct stream_interface *si)
|
||||
/* we may have to close a pending connection, and mark the
|
||||
* response buffer as shutr
|
||||
*/
|
||||
conn_xprt_close(si->conn);
|
||||
if (conn->ctrl)
|
||||
fd_delete(si->conn->t.sock.fd);
|
||||
conn_full_close(si->conn);
|
||||
/* fall through */
|
||||
case SI_ST_CER:
|
||||
case SI_ST_QUE:
|
||||
@ -1166,8 +1162,7 @@ void stream_sock_read0(struct stream_interface *si)
|
||||
|
||||
do_close:
|
||||
/* OK we completely close the socket here just as if we went through si_shut[rw]() */
|
||||
conn_xprt_close(si->conn);
|
||||
fd_delete(si->conn->t.sock.fd);
|
||||
conn_full_close(si->conn);
|
||||
|
||||
si->ib->flags &= ~CF_SHUTR_NOW;
|
||||
si->ib->flags |= CF_SHUTR;
|
||||
|
Loading…
Reference in New Issue
Block a user