mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	jack: queue free of old mem in node_set_io as well
Avoid freeing the old io Position area before the data loop has managed to get a pointer to it. Queue a free operation that will be executed from the main loop after the data loop has the io area. Fixes a crash when stressing jack clients to switch between drivers.
This commit is contained in:
		
							parent
							
								
									9da01413a1
								
							
						
					
					
						commit
						1d0d67da1c
					
				
					 1 changed files with 33 additions and 31 deletions
				
			
		|  | @ -2177,6 +2177,37 @@ static int update_driver_activation(struct client *c) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int | ||||||
|  | do_memmap_free(struct spa_loop *loop, | ||||||
|  |                 bool async, uint32_t seq, const void *data, size_t size, void *user_data) | ||||||
|  | { | ||||||
|  | 	struct client *c = user_data; | ||||||
|  | 	struct pw_memmap *mm = *((struct pw_memmap **)data); | ||||||
|  | 	pw_log_trace("memmap %p free", mm); | ||||||
|  | 	pw_memmap_free(mm); | ||||||
|  | 	pw_core_set_paused(c->core, false); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | do_queue_memmap_free(struct spa_loop *loop, | ||||||
|  |                 bool async, uint32_t seq, const void *data, size_t size, void *user_data) | ||||||
|  | { | ||||||
|  | 	struct client *c = user_data; | ||||||
|  | 	pw_loop_invoke(c->context.l, do_memmap_free, 0, data, size, false, c); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void queue_memmap_free(struct client *c, struct pw_memmap *mem) | ||||||
|  | { | ||||||
|  | 	if (mem != NULL) { | ||||||
|  | 		mem->tag[0] = SPA_ID_INVALID; | ||||||
|  | 		pw_core_set_paused(c->core, true); | ||||||
|  | 		pw_data_loop_invoke(c->loop, | ||||||
|  | 			do_queue_memmap_free, SPA_ID_INVALID, &mem, sizeof(&mem), false, c); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int client_node_set_io(void *data, | static int client_node_set_io(void *data, | ||||||
| 			uint32_t id, | 			uint32_t id, | ||||||
| 			uint32_t mem_id, | 			uint32_t mem_id, | ||||||
|  | @ -2209,6 +2240,8 @@ static int client_node_set_io(void *data, | ||||||
| 		c->position = ptr; | 		c->position = ptr; | ||||||
| 		c->driver_id = ptr ? c->position->clock.id : SPA_ID_INVALID; | 		c->driver_id = ptr ? c->position->clock.id : SPA_ID_INVALID; | ||||||
| 		update_driver_activation(c); | 		update_driver_activation(c); | ||||||
|  | 		queue_memmap_free(c, old); | ||||||
|  | 		old = NULL; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		break; | 		break; | ||||||
|  | @ -2876,37 +2909,6 @@ static int client_node_port_use_buffers(void *data, | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int |  | ||||||
| do_memmap_free(struct spa_loop *loop, |  | ||||||
|                 bool async, uint32_t seq, const void *data, size_t size, void *user_data) |  | ||||||
| { |  | ||||||
| 	struct client *c = user_data; |  | ||||||
| 	struct pw_memmap *mm = *((struct pw_memmap **)data); |  | ||||||
| 	pw_log_trace("memmap %p free", mm); |  | ||||||
| 	pw_memmap_free(mm); |  | ||||||
| 	pw_core_set_paused(c->core, false); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int |  | ||||||
| do_queue_memmap_free(struct spa_loop *loop, |  | ||||||
|                 bool async, uint32_t seq, const void *data, size_t size, void *user_data) |  | ||||||
| { |  | ||||||
| 	struct client *c = user_data; |  | ||||||
| 	pw_loop_invoke(c->context.l, do_memmap_free, 0, data, size, false, c); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void queue_memmap_free(struct client *c, struct pw_memmap *mem) |  | ||||||
| { |  | ||||||
| 	if (mem != NULL) { |  | ||||||
| 		mem->tag[0] = SPA_ID_INVALID; |  | ||||||
| 		pw_core_set_paused(c->core, true); |  | ||||||
| 		pw_data_loop_invoke(c->loop, |  | ||||||
| 			do_queue_memmap_free, SPA_ID_INVALID, &mem, sizeof(&mem), false, c); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int client_node_port_set_io(void *data, | static int client_node_port_set_io(void *data, | ||||||
|                              enum spa_direction direction, |                              enum spa_direction direction, | ||||||
|                              uint32_t port_id, |                              uint32_t port_id, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Wim Taymans
						Wim Taymans