From 9b808558219f6dd37a1733c9720dcbd33178606e Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 1 Oct 2024 10:44:12 +0200 Subject: [PATCH] impl-node: make exported nodes complete state change sync Don't queue an async state change completion for exported nodes. The server sends a ping to check for completion and we want this ping reply to happen after the state completion. Consider the case where we have a follower and a driver, the follower is sent the Start/Ping commands and replies to the ping but is still processing the state change async. The server can then Start the driver, which will then try to schedule the (still starting) follower and fail. We could add the ping to the work queue as well but that creates complications because modules (clients) and server share the same work queues right now and block each other completions. We could also make a method to process the work queue immediately but that would be dangerous as well because it could contain a BUSY item from some module that would block things. --- src/pipewire/impl-node.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 30bbc9a9d..9fd254271 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -2797,9 +2797,17 @@ int pw_impl_node_set_state(struct pw_impl_node *node, enum pw_node_state state) * will wait until all previous items in the work queue are * completed */ impl->pending_state = state; - impl->pending_id = pw_work_queue_add(impl->work, - node, res == EBUSY ? -EBUSY : res, - on_state_complete, SPA_INT_TO_PTR(state)); + if (node->exported) { + /* exported nodes must complete immediately. This is important + * because the server sends ping to check completion. The server + * will only send Start to driver nodes when all clients are + * ready for processing. */ + on_state_complete(node, SPA_INT_TO_PTR(state), -EBUSY, 0); + } else { + impl->pending_id = pw_work_queue_add(impl->work, + node, res == EBUSY ? -EBUSY : res, + on_state_complete, SPA_INT_TO_PTR(state)); + } } return res; }