mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
impl-node: Don't schedule non-active node
Avoid scheduling non-active nodes by removing the eventfd source from the data loop when the node is deactivated. Read any old value from the eventfd when starting the node again in case it has been written to while the source was removed from the loop. The ready callback can still be called when the node isn't active since it is not called via the eventfd.
This commit is contained in:
parent
75007ae94f
commit
968508cf4d
1 changed files with 39 additions and 29 deletions
|
|
@ -158,11 +158,49 @@ static void remove_node(struct pw_impl_node *this)
|
||||||
this->rt.driver_target.node = NULL;
|
this->rt.driver_target.node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_node_add(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||||
|
{
|
||||||
|
struct pw_impl_node *this = user_data;
|
||||||
|
struct pw_impl_node *driver = this->driver_node;
|
||||||
|
|
||||||
|
this->added = true;
|
||||||
|
if (this->source.loop == NULL) {
|
||||||
|
struct spa_system *data_system = this->context->data_system;
|
||||||
|
uint64_t dummy;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/* clear the eventfd in case it was written to while the node was stopped */
|
||||||
|
res = spa_system_eventfd_read(data_system, this->source.fd, &dummy);
|
||||||
|
if (SPA_UNLIKELY(res != -EAGAIN && res != 0))
|
||||||
|
pw_log_warn("%p: read failed %m", this);
|
||||||
|
|
||||||
|
spa_loop_add_source(loop, &this->source);
|
||||||
|
add_node(this, driver);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_node_remove(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||||
|
{
|
||||||
|
struct pw_impl_node *this = user_data;
|
||||||
|
if (this->source.loop != NULL) {
|
||||||
|
spa_loop_remove_source(loop, &this->source);
|
||||||
|
remove_node(this);
|
||||||
|
}
|
||||||
|
this->added = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void node_deactivate(struct pw_impl_node *this)
|
static void node_deactivate(struct pw_impl_node *this)
|
||||||
{
|
{
|
||||||
struct pw_impl_port *port;
|
struct pw_impl_port *port;
|
||||||
struct pw_impl_link *link;
|
struct pw_impl_link *link;
|
||||||
|
|
||||||
|
/* make sure the node doesn't get woken up while not active */
|
||||||
|
pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this);
|
||||||
|
|
||||||
pw_log_debug("%p: deactivate", this);
|
pw_log_debug("%p: deactivate", this);
|
||||||
spa_list_for_each(port, &this->input_ports, link) {
|
spa_list_for_each(port, &this->input_ports, link) {
|
||||||
spa_list_for_each(link, &port->links, input_link)
|
spa_list_for_each(link, &port->links, input_link)
|
||||||
|
|
@ -325,34 +363,6 @@ static void emit_params(struct pw_impl_node *node, uint32_t *changed_ids, uint32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
do_node_add(struct spa_loop *loop,
|
|
||||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
|
||||||
{
|
|
||||||
struct pw_impl_node *this = user_data;
|
|
||||||
struct pw_impl_node *driver = this->driver_node;
|
|
||||||
|
|
||||||
if (this->source.loop == NULL) {
|
|
||||||
spa_loop_add_source(loop, &this->source);
|
|
||||||
add_node(this, driver);
|
|
||||||
}
|
|
||||||
this->added = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_node_remove(struct spa_loop *loop,
|
|
||||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
|
||||||
{
|
|
||||||
struct pw_impl_node *this = user_data;
|
|
||||||
if (this->source.loop != NULL) {
|
|
||||||
spa_loop_remove_source(loop, &this->source);
|
|
||||||
remove_node(this);
|
|
||||||
}
|
|
||||||
this->added = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, int res, char *error)
|
static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, int res, char *error)
|
||||||
{
|
{
|
||||||
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
|
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
|
||||||
|
|
@ -1636,7 +1646,7 @@ static int node_ready(void *data, int status)
|
||||||
node->driver, node->exported, driver, status, node->added);
|
node->driver, node->exported, driver, status, node->added);
|
||||||
|
|
||||||
if (!node->added) {
|
if (!node->added) {
|
||||||
pw_log_warn("%p: ready non-active node", node);
|
pw_log_warn("%p: ready non-active node %s in state %d", node, node->name, node->info.state);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue