MINOR: connection: implement conn_release()

Several places reuse the same code to ensure a connection is properly
freed, either via its MUX or by calling the proper set of functions.
Factorize all of this in a new function conn_release().

This new function is now called via session_free() and
session_accept_fd(). It will also be reused on delete server to
proactively close idle connections.
This commit is contained in:
Amaury Denoyelle 2024-03-20 15:37:09 +01:00
parent 10ece2cf66
commit ff2e71ae24
3 changed files with 21 additions and 21 deletions

View File

@ -89,6 +89,7 @@ void conn_delete_from_tree(struct connection *conn);
void conn_init(struct connection *conn, void *target); void conn_init(struct connection *conn, void *target);
struct connection *conn_new(void *target); struct connection *conn_new(void *target);
void conn_free(struct connection *conn); void conn_free(struct connection *conn);
void conn_release(struct connection *conn);
struct conn_hash_node *conn_alloc_hash_node(struct connection *conn); struct conn_hash_node *conn_alloc_hash_node(struct connection *conn);
struct sockaddr_storage *sockaddr_alloc(struct sockaddr_storage **sap, const struct sockaddr_storage *orig, socklen_t len); struct sockaddr_storage *sockaddr_alloc(struct sockaddr_storage **sap, const struct sockaddr_storage *orig, socklen_t len);
void sockaddr_free(struct sockaddr_storage **sap); void sockaddr_free(struct sockaddr_storage **sap);

View File

@ -603,6 +603,21 @@ void conn_free(struct connection *conn)
pool_free(pool_head_connection, conn); pool_free(pool_head_connection, conn);
} }
/* Close all <conn> internal layers accordingly prior to freeing it. */
void conn_release(struct connection *conn)
{
if (conn->mux) {
conn->mux->destroy(conn->ctx);
}
else {
conn_stop_tracking(conn);
conn_full_close(conn);
if (conn->destroy_cb)
conn->destroy_cb(conn);
conn_free(conn);
}
}
struct conn_hash_node *conn_alloc_hash_node(struct connection *conn) struct conn_hash_node *conn_alloc_hash_node(struct connection *conn)
{ {
struct conn_hash_node *hash_node = NULL; struct conn_hash_node *hash_node = NULL;

View File

@ -89,18 +89,9 @@ void session_free(struct session *sess)
list_for_each_entry_safe(pconns, pconns_back, &sess->priv_conns, sess_el) { list_for_each_entry_safe(pconns, pconns_back, &sess->priv_conns, sess_el) {
list_for_each_entry_safe(conn, conn_back, &pconns->conn_list, sess_el) { list_for_each_entry_safe(conn, conn_back, &pconns->conn_list, sess_el) {
LIST_DEL_INIT(&conn->sess_el); LIST_DEL_INIT(&conn->sess_el);
if (conn->mux) {
conn->owner = NULL; conn->owner = NULL;
conn->flags &= ~CO_FL_SESS_IDLE; conn->flags &= ~CO_FL_SESS_IDLE;
conn->mux->destroy(conn->ctx); conn_release(conn);
} else {
/* We have a connection, but not yet an associated mux.
* So destroy it now.
*/
conn_stop_tracking(conn);
conn_full_close(conn);
conn_free(conn);
}
} }
MT_LIST_DELETE(&pconns->srv_el); MT_LIST_DELETE(&pconns->srv_el);
pool_free(pool_head_sess_priv_conns, pconns); pool_free(pool_head_sess_priv_conns, pconns);
@ -323,15 +314,8 @@ int session_accept_fd(struct connection *cli_conn)
MSG_DONTWAIT|MSG_NOSIGNAL); MSG_DONTWAIT|MSG_NOSIGNAL);
} }
if (cli_conn->mux) {
/* Mux is already initialized for active reversed connection. */ /* Mux is already initialized for active reversed connection. */
cli_conn->mux->destroy(cli_conn->ctx); conn_release(cli_conn);
}
else {
conn_stop_tracking(cli_conn);
conn_full_close(cli_conn);
conn_free(cli_conn);
}
listener_release(l); listener_release(l);
return ret; return ret;
} }