impl-node: fix required state for async driver nodes

When the node activation.required was incremented because it was a
driver, only decrement it in that case, regardless of the current driver
state of the node.

This fixes the case of KODI where the required field gets out of sync
and things become unschedulable.

Fixes #4087
This commit is contained in:
Wim Taymans 2024-07-01 10:36:09 +02:00
parent 7b4c0dd5ec
commit b8d07e40d6
2 changed files with 15 additions and 8 deletions

View file

@ -112,13 +112,17 @@ static inline void activate_target(struct pw_impl_node *node, struct pw_node_tar
{
struct pw_node_activation_state *state = &t->activation->state[0];
if (!t->active) {
if ((!node->async || node->driving) && !node->exported) {
SPA_ATOMIC_INC(state->required);
SPA_ATOMIC_INC(state->pending);
if (!node->async || node->driving) {
if (!node->exported) {
SPA_ATOMIC_INC(state->required);
SPA_ATOMIC_INC(state->pending);
}
}
t->active_driving = node->driving;
t->active = true;
pw_log_debug("%p: target state:%p id:%d pending:%d/%d",
node, state, t->id, state->pending, state->required);
pw_log_debug("%p: target state:%p id:%d pending:%d/%d %d:%d:%d",
node, state, t->id, state->pending, state->required,
node->async, node->driving, node->exported);
}
}
@ -126,7 +130,7 @@ static inline void deactivate_target(struct pw_impl_node *node, struct pw_node_t
{
if (t->active) {
struct pw_node_activation_state *state = &t->activation->state[0];
if (!node->async || node->driving) {
if (!node->async || t->active_driving) {
/* the driver copies the required to the pending state
* so first try to resume the node and then decrement the
* required state. This way we either resume with the old value
@ -137,8 +141,10 @@ static inline void deactivate_target(struct pw_impl_node *node, struct pw_node_t
SPA_ATOMIC_DEC(state->required);
}
t->active = false;
pw_log_debug("%p: target state:%p id:%d pending:%d/%d trigger:%"PRIu64,
node, state, t->id, state->pending, state->required, trigger);
t->active_driving = false;
pw_log_debug("%p: target state:%p id:%d pending:%d/%d %d:%d:%d trigger:%"PRIu64,
node, state, t->id, state->pending, state->required,
node->async, node->driving, node->exported, trigger);
}
}

View file

@ -541,6 +541,7 @@ struct pw_node_target {
int fd;
void (*trigger)(struct pw_node_target *t, uint64_t nsec);
unsigned int active:1;
unsigned int active_driving:1;
unsigned int added:1;
};