impl-node: update required state atomically

We might be updating the required state from multiple threads in the
future.
This commit is contained in:
Wim Taymans 2024-05-28 13:09:30 +02:00
parent 315dc7cdad
commit eaa3d04bcc
3 changed files with 9 additions and 9 deletions

View file

@ -101,7 +101,7 @@ static void pw_node_peer_activate(struct pw_node_peer *peer)
if (!peer->target.active && peer->output->rt.driver_target.node != NULL) { if (!peer->target.active && peer->output->rt.driver_target.node != NULL) {
if (!peer->output->async) if (!peer->output->async)
state->required++; SPA_ATOMIC_INC(state->required);
peer->target.active = true; peer->target.active = true;
} }
} }
@ -118,7 +118,7 @@ static void pw_node_peer_deactivate(struct pw_node_peer *peer)
if (peer->target.active) { if (peer->target.active) {
if (!peer->output->async) { if (!peer->output->async) {
state->required--; SPA_ATOMIC_DEC(state->required);
trigger_target(&peer->target, get_time_ns(peer->target.system)); trigger_target(&peer->target, get_time_ns(peer->target.system));
} }
peer->target.active = false; peer->target.active = false;

View file

@ -170,7 +170,7 @@ do_node_add(struct spa_loop *loop, bool async, uint32_t seq,
spa_list_append(&driver->rt.target_list, &this->rt.target.link); spa_list_append(&driver->rt.target_list, &this->rt.target.link);
nstate = &this->rt.target.activation->state[0]; nstate = &this->rt.target.activation->state[0];
if (!this->rt.target.active) { if (!this->rt.target.active) {
nstate->required++; SPA_ATOMIC_INC(nstate->required);
this->rt.target.active = true; this->rt.target.active = true;
} }
/* now increment the required states of all this node targets, including /* now increment the required states of all this node targets, including
@ -179,7 +179,7 @@ do_node_add(struct spa_loop *loop, bool async, uint32_t seq,
dstate = &t->activation->state[0]; dstate = &t->activation->state[0];
if (!t->active) { if (!t->active) {
if (!this->async) if (!this->async)
dstate->required++; SPA_ATOMIC_INC(dstate->required);
t->active = true; t->active = true;
} }
pw_log_trace("%p: driver state:%p pending:%d/%d, node state:%p pending:%d/%d", pw_log_trace("%p: driver state:%p pending:%d/%d, node state:%p pending:%d/%d",
@ -214,7 +214,7 @@ do_node_remove(struct spa_loop *loop, bool async, uint32_t seq,
spa_list_remove(&this->rt.target.link); spa_list_remove(&this->rt.target.link);
nstate = &this->rt.target.activation->state[0]; nstate = &this->rt.target.activation->state[0];
if (this->rt.target.active) { if (this->rt.target.active) {
nstate->required--; SPA_ATOMIC_DEC(nstate->required);
this->rt.target.active = false; this->rt.target.active = false;
} }
@ -222,7 +222,7 @@ do_node_remove(struct spa_loop *loop, bool async, uint32_t seq,
dstate = &t->activation->state[0]; dstate = &t->activation->state[0];
if (t->active) { if (t->active) {
if (!this->async) { if (!this->async) {
dstate->required--; SPA_ATOMIC_DEC(dstate->required);
if (old_state != PW_NODE_ACTIVATION_FINISHED) if (old_state != PW_NODE_ACTIVATION_FINISHED)
trigger_target(t, get_time_ns(this->rt.target.system)); trigger_target(t, get_time_ns(this->rt.target.system));
} }
@ -1135,9 +1135,9 @@ static void check_properties(struct pw_impl_node *node)
if (trigger != node->trigger) { if (trigger != node->trigger) {
node->trigger = trigger; node->trigger = trigger;
if (trigger) if (trigger)
node->rt.target.activation->state[0].required++; SPA_ATOMIC_INC(node->rt.target.activation->state[0].required);
else else
node->rt.target.activation->state[0].required--; SPA_ATOMIC_DEC(node->rt.target.activation->state[0].required);
} }
/* group defines what nodes are scheduled together */ /* group defines what nodes are scheduled together */

View file

@ -524,7 +524,7 @@ struct pw_node_activation_state {
static inline void pw_node_activation_state_reset(struct pw_node_activation_state *state) static inline void pw_node_activation_state_reset(struct pw_node_activation_state *state)
{ {
state->pending = state->required; SPA_ATOMIC_STORE(state->pending, SPA_ATOMIC_LOAD(state->required));
} }
#define pw_node_activation_state_dec(s) (SPA_ATOMIC_DEC(s->pending) == 0) #define pw_node_activation_state_dec(s) (SPA_ATOMIC_DEC(s->pending) == 0)