impl-node: improve suspend

Make sure we can only suspend when the node is (going to) IDLE. We don't
really want to suspend a node that is running or starting up.

Deactivate the node while we suspend so that graph recalc because of the
unprepared links will not try to prepare the links again.

This might fix a race when a node is suspended at the same time it is
started and cause silence. It also fixes the issue of total silence when
doing "pactl suspend <node> 1" on a running node.
This commit is contained in:
Wim Taymans 2023-08-21 15:28:36 +02:00
parent cd24fe2fe9
commit 3c47fa894b

View file

@ -434,15 +434,19 @@ static void node_update_state(struct pw_impl_node *node, enum pw_node_state stat
static int suspend_node(struct pw_impl_node *this)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
int res = 0;
struct pw_impl_port *p;
bool active = this->active;
pw_log_debug("%p: suspend node state:%s", this,
pw_node_state_as_string(this->info.state));
if (this->info.state > 0 && this->info.state <= PW_NODE_STATE_SUSPENDED)
if (this->info.state != PW_NODE_STATE_ERROR &&
impl->pending_state != PW_NODE_STATE_IDLE)
return 0;
this->active = false;
node_deactivate(this);
spa_list_for_each(p, &this->input_ports, link) {
@ -473,6 +477,7 @@ static int suspend_node(struct pw_impl_node *this)
pw_log_warn("%p: suspend node error %s", this, spa_strerror(res));
node_update_state(this, PW_NODE_STATE_SUSPENDED, 0, NULL);
this->active = active;
return res;
}