mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	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:
		
							parent
							
								
									7b4c0dd5ec
								
							
						
					
					
						commit
						b8d07e40d6
					
				
					 2 changed files with 15 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue