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