From 27b9f469b5caa7062d38cf94aa833c81717ae148 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 30 Jun 2021 09:34:46 +0200 Subject: [PATCH] impl-port: avoid recalculating latency on destroying port Fixes a crash. Fixes #1371 --- src/pipewire/impl-port.c | 55 +++++++++++++++++++--------------------- src/pipewire/private.h | 1 + 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index c1a409008..d6fbfa948 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -1081,6 +1081,7 @@ void pw_impl_port_destroy(struct pw_impl_port *port) pw_log_debug(NAME" %p: destroy", port); + port->destroying = true; pw_impl_port_emit_destroy(port); pw_impl_port_unlink(port); @@ -1295,40 +1296,18 @@ int pw_impl_port_for_each_link(struct pw_impl_port *port, return res; } -static int port_set_latency(struct pw_impl_port *port, struct spa_latency_info *latency) +int pw_impl_port_recalc_latency(struct pw_impl_port *port) { - struct spa_latency_info *current; + struct pw_impl_link *l; + struct spa_latency_info latency, *current; + struct pw_impl_port *other; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - current = &port->latency[latency->direction]; - - if (spa_latency_info_compare(current, latency) == 0) + if (port->destroying) return 0; - *current = *latency; - - pw_log_debug("port %p: set %s latency %f-%f %d-%d %"PRIu64"-%"PRIu64, port, - pw_direction_as_string(latency->direction), - latency->min_quantum, latency->max_quantum, - latency->min_rate, latency->max_rate, - latency->min_ns, latency->max_ns); - - if (!port->have_latency_param) - return 0; - - spa_pod_builder_init(&b, buffer, sizeof(buffer)); - param = spa_latency_build(&b, SPA_PARAM_Latency, latency); - return pw_impl_port_set_param(port, SPA_PARAM_Latency, 0, param); -} - -int pw_impl_port_recalc_latency(struct pw_impl_port *port) -{ - struct pw_impl_link *l; - struct spa_latency_info latency; - struct pw_impl_port *other; - latency = SPA_LATENCY_INFO(SPA_DIRECTION_REVERSE(port->direction)); if (port->direction == PW_DIRECTION_OUTPUT) { @@ -1352,8 +1331,26 @@ int pw_impl_port_recalc_latency(struct pw_impl_port *port) latency.min_ns, latency.max_ns); } } - port_set_latency(port, &latency); - return 0; + + current = &port->latency[latency.direction]; + + if (spa_latency_info_compare(current, &latency) == 0) + return 0; + + *current = latency; + + pw_log_debug("port %p: set %s latency %f-%f %d-%d %"PRIu64"-%"PRIu64, port, + pw_direction_as_string(latency.direction), + latency.min_quantum, latency.max_quantum, + latency.min_rate, latency.max_rate, + latency.min_ns, latency.max_ns); + + if (!port->have_latency_param) + return 0; + + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + param = spa_latency_build(&b, SPA_PARAM_Latency, &latency); + return pw_impl_port_set_param(port, SPA_PARAM_Latency, 0, param); } SPA_EXPORT diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 6a83c9e0b..bbcd5b470 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -824,6 +824,7 @@ struct pw_impl_port { struct spa_list node_link; } rt; /**< data only accessed from the data thread */ unsigned int added:1; + unsigned int destroying:1; struct spa_latency_info latency[2]; /**< latencies */ unsigned int have_latency_param:1;