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.
This commit is contained in:
Wim Taymans 2024-10-01 10:44:12 +02:00
parent 9f7c481742
commit 800a25a01f

View file

@ -2780,10 +2780,18 @@ 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 * will wait until all previous items in the work queue are
* completed */ * completed */
impl->pending_state = state; impl->pending_state = 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, impl->pending_id = pw_work_queue_add(impl->work,
node, res == EBUSY ? -EBUSY : res, node, res == EBUSY ? -EBUSY : res,
on_state_complete, SPA_INT_TO_PTR(state)); on_state_complete, SPA_INT_TO_PTR(state));
} }
}
return res; return res;
} }