{
struct connection *conn = h1c->conn;
+ /* The connection was attached to another mux */
+ if (conn && conn->ctx != h1c)
+ conn = NULL;
+
if (h1c) {
if (!LIST_ISEMPTY(&h1c->buf_wait.list)) {
HA_SPIN_LOCK(BUF_WQ_LOCK, &buffer_wq_lock);
tasklet_free(h1c->wait_event.task);
h1s_destroy(h1c->h1s);
- if (h1c->wait_event.events != 0)
- conn->xprt->unsubscribe(conn, h1c->wait_event.events,
- &h1c->wait_event);
pool_free(pool_head_h1c, h1c);
}
- conn->mux = NULL;
- conn->ctx = NULL;
+ if (conn) {
+ conn->mux = NULL;
+ conn->ctx = NULL;
- conn_stop_tracking(conn);
- conn_full_close(conn);
- if (conn->destroy_cb)
- conn->destroy_cb(conn);
- conn_free(conn);
+ conn_force_unsubscribe(conn);
+ conn_stop_tracking(conn);
+ conn_full_close(conn);
+ if (conn->destroy_cb)
+ conn->destroy_cb(conn);
+ conn_free(conn);
+ }
}
/******************************************************/
{
struct h1c *h1c = ctx;
- if (!h1c->h1s)
+ if (!h1c->h1s || !h1c->conn || h1c->conn->ctx != h1c)
h1_release(h1c);
}
{
struct connection *conn = h2c->conn;
+ /* The connection was attached to another mux (unexpected but safer to
+ * check) */
+ if (conn && conn->ctx != h2c)
+ conn = NULL;
+
if (h2c) {
hpack_dht_free(h2c->ddht);
}
if (h2c->wait_event.task)
tasklet_free(h2c->wait_event.task);
- if (h2c->wait_event.events != 0)
- conn->xprt->unsubscribe(conn, h2c->wait_event.events,
- &h2c->wait_event);
pool_free(pool_head_h2c, h2c);
}
- conn->mux = NULL;
- conn->ctx = NULL;
+ if (conn) {
+ conn->mux = NULL;
+ conn->ctx = NULL;
- conn_stop_tracking(conn);
- conn_full_close(conn);
- if (conn->destroy_cb)
- conn->destroy_cb(conn);
- conn_free(conn);
+ conn_force_unsubscribe(conn);
+ conn_stop_tracking(conn);
+ conn_full_close(conn);
+ if (conn->destroy_cb)
+ conn->destroy_cb(conn);
+ conn_free(conn);
+ }
}
{
struct h2c *h2c = ctx;
- if (eb_is_empty(&h2c->streams_by_id))
+ if (eb_is_empty(&h2c->streams_by_id) || !h2c->conn || h2c->conn->ctx != h2c)
h2_release(h2c);
}
{
struct connection *conn = ctx->conn;
- conn_stop_tracking(conn);
- conn_full_close(conn);
- tasklet_free(ctx->wait_event.task);
- conn->mux = NULL;
- conn->ctx = NULL;
- if (conn->destroy_cb)
- conn->destroy_cb(conn);
- /* We don't bother unsubscribing here, as we're about to destroy
- * both the connection and the mux_pt_ctx
- */
- conn_free(conn);
+ /* The connection was attached to another mux */
+ if (conn && conn->ctx != ctx)
+ conn = NULL;
+
+ if (conn) {
+ conn_stop_tracking(conn);
+ conn_full_close(conn);
+ tasklet_free(ctx->wait_event.task);
+ conn->mux = NULL;
+ conn->ctx = NULL;
+ if (conn->destroy_cb)
+ conn->destroy_cb(conn);
+ /* We don't bother unsubscribing here, as we're about to destroy
+ * both the connection and the mux_pt_ctx
+ */
+ conn_free(conn);
+ }
pool_free(pool_head_pt_ctx, ctx);
}
{
struct mux_pt_ctx *pt = ctx;
- if (!(pt->cs))
+ if (!(pt->cs) || !(pt->conn) || pt->conn->ctx != pt)
mux_pt_destroy(pt);
}