From a5f23224d173fd5dfed5933bee00c9d420e08da9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 3 Dec 2022 20:03:00 +0100 Subject: [PATCH] impl-node: activate links immediately Don't wait for the node to be added to the graph before we activate the links to it. We don't do the reverse for shutdown and the activation counters won't actually be updated until the node is added. Waiting can cause race conditions in some specific cases (see in screen sharing unit test) because the driver node can start pushing buffers before the link has sent the Buffer io area to the ports. With this fix, the receiver (input stream) will first trigger the input link activation, then the Start command and then it will be added to the graph. This does not entirely fix the race conditions when starting. Ideally, the driver node should wait until all pending Start commands of the nodes in the graph have completed. --- src/pipewire/impl-link.c | 4 ++-- src/pipewire/impl-node.c | 13 ++----------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index 5eeff5b01..8694f1392 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -622,8 +622,8 @@ int pw_impl_link_activate(struct pw_impl_link *this) pw_log_debug("%p: activate activated:%d state:%s", this, impl->activated, pw_link_state_as_string(this->info.state)); - if (impl->activated || !this->prepared || !impl->inode->active || - !impl->inode->added || !impl->onode->active) + if (impl->activated || !this->prepared || + !impl->inode->active || !impl->onode->active) return 0; if (!impl->io_set) { diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index e2f67ab2d..8c2916c05 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -239,7 +239,7 @@ static int idle_node(struct pw_impl_node *this) return res; } -static void node_activate_outputs(struct pw_impl_node *this) +static void node_activate(struct pw_impl_node *this) { struct pw_impl_port *port; @@ -249,13 +249,6 @@ static void node_activate_outputs(struct pw_impl_node *this) spa_list_for_each(link, &port->links, output_link) pw_impl_link_activate(link); } -} - -static void node_activate_inputs(struct pw_impl_node *this) -{ - struct pw_impl_port *port; - - pw_log_debug("%p: activate", this); spa_list_for_each(port, &this->input_ports, link) { struct pw_impl_link *link; spa_list_for_each(link, &port->links, input_link) @@ -268,9 +261,7 @@ static int start_node(struct pw_impl_node *this) struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); int res = 0; - /* First activate the outputs so that when the node starts pushing, - * we can process the outputs */ - node_activate_outputs(this); + node_activate(this); if (impl->pending_state >= PW_NODE_STATE_RUNNING) return 0;