mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
impl-node: always INACTIVATE when stopping
A remote node is prepared when the Start command sync reply has been received. If we however quickly switch from active to inactive, the pending reply is cancelled but the remote node will have set the FINISHED status and will be ready to be scheduled. Make it so that we always set the INACTIVE status when the node is canceled and unprepared, even if we didn't get the reply and the node was not prepared. Fixes #4122
This commit is contained in:
parent
0dc17d8d88
commit
32e4553a05
2 changed files with 11 additions and 7 deletions
|
|
@ -177,7 +177,8 @@ do_node_prepare(struct spa_loop *loop, bool async, uint32_t seq,
|
|||
uint64_t dummy;
|
||||
int res;
|
||||
|
||||
pw_log_trace("%p: prepare %d remote:%d", this, this->rt.prepared, this->remote);
|
||||
pw_log_trace("%p: prepare %d remote:%d exported:%d", this, this->rt.prepared,
|
||||
this->remote, this->exported);
|
||||
|
||||
if (this->rt.prepared)
|
||||
return 0;
|
||||
|
|
@ -216,10 +217,8 @@ do_node_unprepare(struct spa_loop *loop, bool async, uint32_t seq,
|
|||
int old_state;
|
||||
uint64_t trigger = 0;
|
||||
|
||||
pw_log_trace("%p: unprepare %d remote:%d", this, this->rt.prepared, this->remote);
|
||||
|
||||
if (!this->rt.prepared)
|
||||
return 0;
|
||||
pw_log_trace("%p: unprepare %d remote:%d exported:%d", this, this->rt.prepared,
|
||||
this->remote, this->exported);
|
||||
|
||||
if (!this->exported) {
|
||||
/* We mark ourself as finished now, this will avoid going further into the process loop
|
||||
|
|
@ -227,9 +226,12 @@ do_node_unprepare(struct spa_loop *loop, bool async, uint32_t seq,
|
|||
* If we were supposed to be scheduled make sure we continue the graph for the peers we
|
||||
* were supposed to trigger */
|
||||
old_state = SPA_ATOMIC_XCHG(this->rt.target.activation->status, PW_NODE_ACTIVATION_INACTIVE);
|
||||
if (old_state != PW_NODE_ACTIVATION_FINISHED)
|
||||
if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state))
|
||||
trigger = get_time_ns(this->rt.target.system);
|
||||
}
|
||||
if (!this->rt.prepared)
|
||||
return 0;
|
||||
|
||||
if (!this->remote)
|
||||
spa_loop_remove_source(loop, &this->source);
|
||||
|
||||
|
|
@ -861,7 +863,7 @@ do_remove_target(struct spa_loop *loop,
|
|||
if (node->rt.prepared) {
|
||||
int old_state = SPA_ATOMIC_LOAD(node->rt.target.activation->status);
|
||||
uint64_t trigger = 0;
|
||||
if (old_state != PW_NODE_ACTIVATION_FINISHED)
|
||||
if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state))
|
||||
trigger = get_time_ns(node->rt.target.system);
|
||||
deactivate_target(node, t, trigger);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -563,6 +563,8 @@ static inline void copy_target(struct pw_node_target *dst, const struct pw_node_
|
|||
*/
|
||||
#define PW_VERSION_NODE_ACTIVATION 1
|
||||
|
||||
#define PW_NODE_ACTIVATION_PENDING_TRIGGER(status) ((status) <= PW_NODE_ACTIVATION_AWAKE)
|
||||
|
||||
/* nodes start as INACTIVE, when they are ready to be scheduled, they add their
|
||||
* fd to the loop and change status to FINISHED. When the node shuts down, the
|
||||
* status is set back to INACTIVE.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue