mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
loop: keep a free_list of sources
When a source is destroyed, move it to a free_list and reuse the memory when a new source is made. This way we can avoid doing a free() from the epoll thread.
This commit is contained in:
parent
f2452a6af7
commit
34796d5bb8
1 changed files with 41 additions and 38 deletions
|
|
@ -81,6 +81,7 @@ struct impl {
|
|||
|
||||
struct spa_list source_list;
|
||||
struct spa_list destroy_list;
|
||||
struct spa_list free_list;
|
||||
struct spa_hook_list hooks_list;
|
||||
|
||||
struct spa_ratelimit rate_limit;
|
||||
|
|
@ -711,20 +712,14 @@ static int loop_accept(void *object)
|
|||
return -pthread_cond_signal(&impl->accept_cond);
|
||||
}
|
||||
|
||||
static inline void free_source(struct source_impl *s)
|
||||
{
|
||||
detach_source(&s->source);
|
||||
free(s);
|
||||
}
|
||||
|
||||
static inline void process_destroy(struct impl *impl)
|
||||
{
|
||||
struct source_impl *source, *tmp;
|
||||
|
||||
spa_list_for_each_safe(source, tmp, &impl->destroy_list, link)
|
||||
free_source(source);
|
||||
|
||||
spa_list_init(&impl->destroy_list);
|
||||
struct source_impl *s;
|
||||
spa_list_consume(s, &impl->destroy_list, link) {
|
||||
spa_list_remove(&s->link);
|
||||
detach_source(&s->source);
|
||||
spa_list_append(&s->impl->free_list, &s->link);
|
||||
}
|
||||
}
|
||||
|
||||
struct cancellation_handler_data {
|
||||
|
|
@ -843,6 +838,24 @@ static int loop_iterate(void *object, int timeout)
|
|||
return nfds;
|
||||
}
|
||||
|
||||
static struct source_impl *get_source(struct impl *impl)
|
||||
{
|
||||
struct source_impl *source;
|
||||
|
||||
if (!spa_list_is_empty(&impl->free_list)) {
|
||||
source = spa_list_first(&impl->free_list, struct source_impl, link);
|
||||
spa_list_remove(&source->link);
|
||||
spa_zero(*source);
|
||||
} else {
|
||||
source = calloc(1, sizeof(struct source_impl));
|
||||
}
|
||||
if (source != NULL) {
|
||||
source->impl = impl;
|
||||
spa_list_insert(&impl->source_list, &source->link);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
static void source_io_func(struct spa_source *source)
|
||||
{
|
||||
struct source_impl *s = SPA_CONTAINER_OF(source, struct source_impl, source);
|
||||
|
|
@ -859,7 +872,7 @@ static struct spa_source *loop_add_io(void *object,
|
|||
struct source_impl *source;
|
||||
int res;
|
||||
|
||||
source = calloc(1, sizeof(struct source_impl));
|
||||
source = get_source(impl);
|
||||
if (source == NULL)
|
||||
goto error_exit;
|
||||
|
||||
|
|
@ -867,7 +880,6 @@ static struct spa_source *loop_add_io(void *object,
|
|||
source->source.data = data;
|
||||
source->source.fd = fd;
|
||||
source->source.mask = mask;
|
||||
source->impl = impl;
|
||||
source->close = close;
|
||||
source->func.io = func;
|
||||
|
||||
|
|
@ -885,9 +897,6 @@ static struct spa_source *loop_add_io(void *object,
|
|||
spa_log_trace(impl->log, "%p: adding fallback %p", impl,
|
||||
source->fallback);
|
||||
}
|
||||
|
||||
spa_list_insert(&impl->source_list, &source->link);
|
||||
|
||||
return &source->source;
|
||||
|
||||
error_exit_free:
|
||||
|
|
@ -952,7 +961,7 @@ static struct spa_source *loop_add_idle(void *object,
|
|||
struct source_impl *source;
|
||||
int res;
|
||||
|
||||
source = calloc(1, sizeof(struct source_impl));
|
||||
source = get_source(impl);
|
||||
if (source == NULL)
|
||||
goto error_exit;
|
||||
|
||||
|
|
@ -962,7 +971,6 @@ static struct spa_source *loop_add_idle(void *object,
|
|||
source->source.func = source_idle_func;
|
||||
source->source.data = data;
|
||||
source->source.fd = res;
|
||||
source->impl = impl;
|
||||
source->close = true;
|
||||
source->source.mask = SPA_IO_IN;
|
||||
source->func.idle = func;
|
||||
|
|
@ -970,8 +978,6 @@ static struct spa_source *loop_add_idle(void *object,
|
|||
if ((res = loop_add_source(impl, &source->source)) < 0)
|
||||
goto error_exit_close;
|
||||
|
||||
spa_list_insert(&impl->source_list, &source->link);
|
||||
|
||||
if (enabled)
|
||||
loop_enable_idle(impl, &source->source, true);
|
||||
|
||||
|
|
@ -1008,7 +1014,7 @@ static struct spa_source *loop_add_event(void *object,
|
|||
struct source_impl *source;
|
||||
int res;
|
||||
|
||||
source = calloc(1, sizeof(struct source_impl));
|
||||
source = get_source(impl);
|
||||
if (source == NULL)
|
||||
goto error_exit;
|
||||
|
||||
|
|
@ -1019,15 +1025,12 @@ static struct spa_source *loop_add_event(void *object,
|
|||
source->source.data = data;
|
||||
source->source.fd = res;
|
||||
source->source.mask = SPA_IO_IN;
|
||||
source->impl = impl;
|
||||
source->close = true;
|
||||
source->func.event = func;
|
||||
|
||||
if ((res = loop_add_source(impl, &source->source)) < 0)
|
||||
goto error_exit_close;
|
||||
|
||||
spa_list_insert(&impl->source_list, &source->link);
|
||||
|
||||
return &source->source;
|
||||
|
||||
error_exit_close:
|
||||
|
|
@ -1076,7 +1079,7 @@ static struct spa_source *loop_add_timer(void *object,
|
|||
struct source_impl *source;
|
||||
int res;
|
||||
|
||||
source = calloc(1, sizeof(struct source_impl));
|
||||
source = get_source(impl);
|
||||
if (source == NULL)
|
||||
goto error_exit;
|
||||
|
||||
|
|
@ -1088,15 +1091,12 @@ static struct spa_source *loop_add_timer(void *object,
|
|||
source->source.data = data;
|
||||
source->source.fd = res;
|
||||
source->source.mask = SPA_IO_IN;
|
||||
source->impl = impl;
|
||||
source->close = true;
|
||||
source->func.timer = func;
|
||||
|
||||
if ((res = loop_add_source(impl, &source->source)) < 0)
|
||||
goto error_exit_close;
|
||||
|
||||
spa_list_insert(&impl->source_list, &source->link);
|
||||
|
||||
return &source->source;
|
||||
|
||||
error_exit_close:
|
||||
|
|
@ -1160,7 +1160,7 @@ static struct spa_source *loop_add_signal(void *object,
|
|||
struct source_impl *source;
|
||||
int res;
|
||||
|
||||
source = calloc(1, sizeof(struct source_impl));
|
||||
source = get_source(impl);
|
||||
if (source == NULL)
|
||||
goto error_exit;
|
||||
|
||||
|
|
@ -1172,15 +1172,12 @@ static struct spa_source *loop_add_signal(void *object,
|
|||
source->source.data = data;
|
||||
source->source.fd = res;
|
||||
source->source.mask = SPA_IO_IN;
|
||||
source->impl = impl;
|
||||
source->close = true;
|
||||
source->func.signal = func;
|
||||
|
||||
if ((res = loop_add_source(impl, &source->source)) < 0)
|
||||
goto error_exit_close;
|
||||
|
||||
spa_list_insert(&impl->source_list, &source->link);
|
||||
|
||||
return &source->source;
|
||||
|
||||
error_exit_close:
|
||||
|
|
@ -1200,8 +1197,6 @@ static void loop_destroy_source(void *object, struct spa_source *source)
|
|||
|
||||
spa_log_trace(s->impl->log, "%p ", s);
|
||||
|
||||
spa_list_remove(&s->link);
|
||||
|
||||
if (s->fallback)
|
||||
loop_destroy_source(s->impl, s->fallback);
|
||||
else
|
||||
|
|
@ -1212,9 +1207,11 @@ static void loop_destroy_source(void *object, struct spa_source *source)
|
|||
source->fd = -1;
|
||||
}
|
||||
|
||||
if (!s->impl->polling)
|
||||
free_source(s);
|
||||
else
|
||||
spa_list_remove(&s->link);
|
||||
if (!s->impl->polling) {
|
||||
detach_source(source);
|
||||
spa_list_insert(&s->impl->free_list, &s->link);
|
||||
} else
|
||||
spa_list_insert(&s->impl->destroy_list, &s->link);
|
||||
}
|
||||
|
||||
|
|
@ -1312,6 +1309,11 @@ static int impl_clear(struct spa_handle *handle)
|
|||
|
||||
spa_list_consume(source, &impl->source_list, link)
|
||||
loop_destroy_source(impl, &source->source);
|
||||
|
||||
spa_list_consume(source, &impl->free_list, link) {
|
||||
spa_list_remove(&source->link);
|
||||
free(source);
|
||||
}
|
||||
for (i = 0; i < impl->n_queues; i++)
|
||||
loop_queue_destroy(impl->queues[i]);
|
||||
|
||||
|
|
@ -1418,6 +1420,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
|
||||
spa_list_init(&impl->source_list);
|
||||
spa_list_init(&impl->destroy_list);
|
||||
spa_list_init(&impl->free_list);
|
||||
spa_hook_list_init(&impl->hooks_list);
|
||||
|
||||
impl->wakeup = loop_add_event(impl, wakeup_func, impl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue