mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	impl-port: only add the port when buffers are negotiated
To avoid crashes when the node is scheduled but buffer have been cleared. See #904
This commit is contained in:
		
							parent
							
								
									b5220c83da
								
							
						
					
					
						commit
						5f7910fcac
					
				
					 2 changed files with 22 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -962,8 +962,6 @@ int pw_impl_port_add(struct pw_impl_port *port, struct pw_impl_node *node)
 | 
			
		|||
	if (node->global)
 | 
			
		||||
		pw_impl_port_register(port, NULL);
 | 
			
		||||
 | 
			
		||||
	pw_loop_invoke(node->data_loop, do_add_port, SPA_ID_INVALID, NULL, 0, false, port);
 | 
			
		||||
 | 
			
		||||
	if (port->state <= PW_IMPL_PORT_STATE_INIT)
 | 
			
		||||
		pw_impl_port_update_state(port, PW_IMPL_PORT_STATE_CONFIGURE, 0, NULL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,10 +1001,13 @@ static void pw_impl_port_remove(struct pw_impl_port *port)
 | 
			
		|||
	if (node == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug(NAME" %p: remove", port);
 | 
			
		||||
	pw_log_debug(NAME" %p: remove added:%d", port, port->added);
 | 
			
		||||
 | 
			
		||||
	pw_loop_invoke(port->node->data_loop, do_remove_port,
 | 
			
		||||
		       SPA_ID_INVALID, NULL, 0, true, port);
 | 
			
		||||
	if (port->added) {
 | 
			
		||||
		pw_loop_invoke(node->data_loop, do_remove_port,
 | 
			
		||||
			       SPA_ID_INVALID, NULL, 0, true, port);
 | 
			
		||||
		port->added = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (SPA_FLAG_IS_SET(port->flags, PW_IMPL_PORT_FLAG_TO_REMOVE)) {
 | 
			
		||||
		if ((res = spa_node_remove_port(node->node, port->direction, port->port_id)) < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1297,6 +1298,10 @@ int pw_impl_port_set_param(struct pw_impl_port *port, uint32_t id, uint32_t flag
 | 
			
		|||
	if (id == SPA_PARAM_Format) {
 | 
			
		||||
		pw_log_debug(NAME" %p: %d %p %d", port, port->state, param, res);
 | 
			
		||||
 | 
			
		||||
		if (port->added) {
 | 
			
		||||
			pw_loop_invoke(node->data_loop, do_remove_port, SPA_ID_INVALID, NULL, 0, true, port);
 | 
			
		||||
			port->added = false;
 | 
			
		||||
		}
 | 
			
		||||
		/* setting the format always destroys the negotiated buffers */
 | 
			
		||||
		pw_buffers_clear(&port->buffers);
 | 
			
		||||
		pw_buffers_clear(&port->mix_buffers);
 | 
			
		||||
| 
						 | 
				
			
			@ -1329,6 +1334,11 @@ static int negotiate_mixer_buffers(struct pw_impl_port *port, uint32_t flags,
 | 
			
		|||
		pw_log_debug(NAME" %p: %d.%d negotiate %d buffers on node: %p",
 | 
			
		||||
				port, port->direction, port->port_id, n_buffers, node->node);
 | 
			
		||||
 | 
			
		||||
		if (port->added) {
 | 
			
		||||
			pw_loop_invoke(node->data_loop, do_remove_port, SPA_ID_INVALID, NULL, 0, true, port);
 | 
			
		||||
			port->added = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pw_buffers_clear(&port->mix_buffers);
 | 
			
		||||
 | 
			
		||||
		if (n_buffers > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1358,6 +1368,10 @@ static int negotiate_mixer_buffers(struct pw_impl_port *port, uint32_t flags,
 | 
			
		|||
			     pw_direction_reverse(port->direction), 0,
 | 
			
		||||
			     0, buffers, n_buffers);
 | 
			
		||||
	}
 | 
			
		||||
	if (!port->added && n_buffers > 0) {
 | 
			
		||||
		pw_loop_invoke(node->data_loop, do_add_port, SPA_ID_INVALID, NULL, 0, false, port);
 | 
			
		||||
		port->added = true;
 | 
			
		||||
	}
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -786,9 +786,10 @@ struct pw_impl_port {
 | 
			
		|||
		struct spa_list mix_list;
 | 
			
		||||
		struct spa_list node_link;
 | 
			
		||||
	} rt;					/**< data only accessed from the data thread */
 | 
			
		||||
	unsigned int added:1;
 | 
			
		||||
 | 
			
		||||
        void *owner_data;		/**< extra owner data */
 | 
			
		||||
        void *user_data;                /**< extra user data */
 | 
			
		||||
	void *owner_data;		/**< extra owner data */
 | 
			
		||||
	void *user_data;                /**< extra user data */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_control_link {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue