void conn_init(struct connection *conn, void *target);
struct connection *conn_new(void *target);
void conn_free(struct connection *conn);
+void conn_release(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);
void sockaddr_free(struct sockaddr_storage **sap);
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 *hash_node = NULL;
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_DEL_INIT(&conn->sess_el);
- if (conn->mux) {
- conn->owner = NULL;
- conn->flags &= ~CO_FL_SESS_IDLE;
- conn->mux->destroy(conn->ctx);
- } 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);
- }
+ conn->owner = NULL;
+ conn->flags &= ~CO_FL_SESS_IDLE;
+ conn_release(conn);
}
MT_LIST_DELETE(&pconns->srv_el);
pool_free(pool_head_sess_priv_conns, pconns);
MSG_DONTWAIT|MSG_NOSIGNAL);
}
- if (cli_conn->mux) {
- /* Mux is already initialized for active reversed connection. */
- cli_conn->mux->destroy(cli_conn->ctx);
- }
- else {
- conn_stop_tracking(cli_conn);
- conn_full_close(cli_conn);
- conn_free(cli_conn);
- }
+ /* Mux is already initialized for active reversed connection. */
+ conn_release(cli_conn);
listener_release(l);
return ret;
}