mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
loop: add back the destroy loop
We need to keep the sources around until all sources are dispatched. If not: source A and B are active after poll, A is dispatched first and removes B, when B is then dispatched, the memory is gone. We don't free the source but simply mark the fd invalid and move it do a destroy list. After all sources are dispatched we destroy. This is safe because removing a source is either done from the poll context (with invoke) or when holding the right locks.
This commit is contained in:
parent
d165b3b842
commit
0eb73f0f06
1 changed files with 15 additions and 1 deletions
|
|
@ -79,6 +79,7 @@ struct impl {
|
|||
struct spa_type_map *map;
|
||||
|
||||
struct spa_list source_list;
|
||||
struct spa_list destroy_list;
|
||||
struct spa_hook_list hooks_list;
|
||||
|
||||
int epoll_fd;
|
||||
|
|
@ -324,6 +325,14 @@ static void loop_leave(struct spa_loop_control *ctrl)
|
|||
impl->thread = 0;
|
||||
}
|
||||
|
||||
static void process_destroy(struct impl *impl)
|
||||
{
|
||||
struct source_impl *source, *tmp;
|
||||
spa_list_for_each_safe(source, tmp, &impl->destroy_list, link)
|
||||
free(source);
|
||||
spa_list_init(&impl->destroy_list);
|
||||
}
|
||||
|
||||
static int loop_iterate(struct spa_loop_control *ctrl, int timeout)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(ctrl, struct impl, control);
|
||||
|
|
@ -353,6 +362,8 @@ static int loop_iterate(struct spa_loop_control *ctrl, int timeout)
|
|||
if (s->rmask && s->fd != -1 && s->loop == loop)
|
||||
s->func(s);
|
||||
}
|
||||
process_destroy(impl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -622,7 +633,7 @@ static void loop_destroy_source(struct spa_source *source)
|
|||
close(source->fd);
|
||||
source->fd = -1;
|
||||
}
|
||||
free(impl);
|
||||
spa_list_insert(&impl->impl->destroy_list, &impl->link);
|
||||
}
|
||||
|
||||
static const struct spa_loop impl_loop = {
|
||||
|
|
@ -689,6 +700,8 @@ static int impl_clear(struct spa_handle *handle)
|
|||
spa_list_for_each_safe(source, tmp, &impl->source_list, link)
|
||||
loop_destroy_source(&source->source);
|
||||
|
||||
process_destroy(impl);
|
||||
|
||||
close(impl->ack_fd);
|
||||
close(impl->epoll_fd);
|
||||
|
||||
|
|
@ -740,6 +753,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
return errno;
|
||||
|
||||
spa_list_init(&impl->source_list);
|
||||
spa_list_init(&impl->destroy_list);
|
||||
spa_hook_list_init(&impl->hooks_list);
|
||||
|
||||
spa_ringbuffer_init(&impl->buffer);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue