From ba374a7b47b690d819e9fc60d2e3b5a2533e52f8 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 9 Jan 2023 11:42:49 +0100 Subject: [PATCH] impl-node: restore running state after reconfigure Add a reconfigure state on the node that is set when the node was IDLE or RUNNING when reconfigured. The node state will be set to the running state as long as the reconfigure state is active. When the node is running, the reconfigure state is unset again and the node is allowed to IDLE as usual. This fixes the case where an IDLE (but not paused node) will be suspended when a rate change happens but will then not resume afterwards. This causes problems with rate changes and nodes that have the suspend disabled by the session manager. They will be suspened anyway and this can cause problems for devices that need to keep running to keep the amplifiers active. Fixes #2929 --- src/pipewire/context.c | 8 +++++++- src/pipewire/impl-node.c | 8 ++++++++ src/pipewire/private.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 2301d34ad..ab798c20e 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -946,6 +946,9 @@ static void reconfigure_driver(struct pw_context *context, struct pw_impl_node * } pw_log_debug("%p: driver %p: '%s' suspend", context, n, n->name); + + if (n->info.state >= PW_NODE_STATE_IDLE) + n->reconfigure = true; pw_impl_node_set_state(n, PW_NODE_STATE_SUSPENDED); } @@ -1180,8 +1183,11 @@ again: if (force_rate) lock_rate = false; + if (n->reconfigure) + running = true; + current_rate = n->current_rate.denom; - if (lock_rate || + if (lock_rate || n->reconfigure || (!force_rate && (n->info.state > PW_NODE_STATE_IDLE))) /* when someone wants us to lock the rate of this driver or diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 015a3096c..6200e8002 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -418,6 +418,14 @@ static void node_update_state(struct pw_impl_node *node, enum pw_node_state stat spa_list_for_each(resource, &node->global->resource_list, link) pw_resource_error(resource, res, error); } + if (node->reconfigure) { + if (state == PW_NODE_STATE_SUSPENDED && + node->pause_on_idle) { + node->reconfigure = false; + } + if (state == PW_NODE_STATE_RUNNING) + node->reconfigure = false; + } if (old == PW_NODE_STATE_RUNNING && state == PW_NODE_STATE_IDLE && node->suspend_on_idle) { diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 8abd68502..92d004508 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -721,6 +721,7 @@ struct pw_impl_node { unsigned int added:1; /**< the node was add to graph */ unsigned int pause_on_idle:1; /**< Pause processing when IDLE */ unsigned int suspend_on_idle:1; + unsigned int reconfigure:1; uint32_t port_user_data_size; /**< extra size for port user data */ -- GitLab