impl-node: rework link activation

Only activate the links when the node is added to a driver. Otherwise
the driver will expect us to decrement the activation counters for the
links but that won't happen because the node will not be processed
yet.

Instead we activate the links that were not activated yet when the
node is activated.

This improves scheduling for newly added links and nodes.
This commit is contained in:
Wim Taymans 2021-03-10 13:06:02 +01:00
parent cc26ef9614
commit 62def0399f
3 changed files with 44 additions and 18 deletions

View file

@ -519,7 +519,10 @@ do_activate_link(struct spa_loop *loop,
spa_list_append(&impl->onode->rt.target_list, &this->rt.target.link);
state = &this->rt.target.activation->state[0];
state->required++;
if (!this->rt.target.active && impl->onode->rt.driver_target.node != NULL) {
state->required++;
this->rt.target.active = true;
}
pw_log_trace(NAME" %p: node:%p state:%p pending:%d/%d", this, impl->inode,
state, state->pending, state->required);
@ -693,7 +696,10 @@ do_deactivate_link(struct spa_loop *loop,
spa_list_remove(&this->rt.target.link);
state = &this->rt.target.activation->state[0];
state->required--;
if (this->rt.target.active) {
state->required--;
this->rt.target.active = false;
}
pw_log_trace(NAME" %p: node:%p state:%p pending:%d/%d", this, impl->inode,
state, state->pending, state->required);

View file

@ -101,6 +101,7 @@ static void node_deactivate(struct pw_impl_node *this)
static void add_node(struct pw_impl_node *this, struct pw_impl_node *driver)
{
struct pw_node_activation_state *dstate, *nstate;
struct pw_node_target *t;
if (this->exported)
return;
@ -114,21 +115,29 @@ static void add_node(struct pw_impl_node *this, struct pw_impl_node *driver)
this->rt.driver_target.data = driver;
spa_list_append(&this->rt.target_list, &this->rt.driver_target.link);
dstate = &this->rt.driver_target.activation->state[0];
dstate->required++;
spa_list_append(&driver->rt.target_list, &this->rt.target.link);
nstate = &this->rt.activation->state[0];
nstate->required++;
if (!this->rt.target.active) {
nstate->required++;
this->rt.target.active = true;
}
pw_log_trace(NAME" %p: driver state:%p pending:%d/%d, node state:%p pending:%d/%d",
this, dstate, dstate->pending, dstate->required,
nstate, nstate->pending, nstate->required);
spa_list_for_each(t, &this->rt.target_list, link) {
dstate = &t->activation->state[0];
if (!t->active) {
dstate->required++;
t->active = true;
}
pw_log_trace(NAME" %p: driver state:%p pending:%d/%d, node state:%p pending:%d/%d",
this, dstate, dstate->pending, dstate->required,
nstate, nstate->pending, nstate->required);
}
}
static void remove_node(struct pw_impl_node *this)
{
struct pw_node_activation_state *dstate, *nstate;
struct pw_node_target *t;
if (this->exported)
return;
@ -137,17 +146,27 @@ static void remove_node(struct pw_impl_node *this)
this, this->rt.driver_target.data,
this->rt.driver_target.activation, this->rt.activation);
spa_list_remove(&this->rt.driver_target.link);
dstate = &this->rt.driver_target.activation->state[0];
dstate->required--;
spa_list_remove(&this->rt.target.link);
nstate = &this->rt.activation->state[0];
nstate->required--;
pw_log_trace(NAME" %p: driver state:%p pending:%d/%d, node state:%p pending:%d/%d",
this, dstate, dstate->pending, dstate->required,
nstate, nstate->pending, nstate->required);
nstate = &this->rt.activation->state[0];
if (this->rt.target.active) {
nstate->required--;
this->rt.target.active = false;
}
spa_list_for_each(t, &this->rt.target_list, link) {
dstate = &t->activation->state[0];
if (t->active) {
dstate->required--;
t->active = false;
}
pw_log_trace(NAME" %p: driver state:%p pending:%d/%d, node state:%p pending:%d/%d",
this, dstate, dstate->pending, dstate->required,
nstate, nstate->pending, nstate->required);
}
spa_list_remove(&this->rt.driver_target.link);
this->rt.driver_target.node = NULL;
}
static int

View file

@ -513,6 +513,7 @@ struct pw_node_target {
struct pw_node_activation *activation;
int (*signal) (void *data);
void *data;
unsigned int active:1;
};
struct pw_node_activation {