From 080090c40e81bea82754ffccbda2f625eed64e06 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Wed, 15 Dec 2021 11:54:08 -0800 Subject: [PATCH] libobs: Do not release while traversing sources for tick obs_source_release should not be called while iterating through the global sources linked list, otherwise the linked list will be compromised. Annoying. Basically the same fix as obsproject/obs-studio#5600, but should be slightly more optimal and a bit more explicit. --- libobs/obs-internal.h | 2 ++ libobs/obs-video.c | 18 +++++++++++++----- libobs/obs.c | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 13e8c7ed1..469982697 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -360,6 +360,8 @@ struct obs_core_data { DARRAY(struct draw_callback) draw_callbacks; DARRAY(struct tick_callback) tick_callbacks; + DARRAY(struct obs_source *) source_iteration_list; + struct obs_view main_view; long long unnamed_index; diff --git a/libobs/obs-video.c b/libobs/obs-video.c index d4e3b1da4..362911f41 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -59,23 +59,31 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time) /* ------------------------------------- */ /* call the tick function of each source */ + da_resize(data->source_iteration_list, 0); + pthread_mutex_lock(&data->sources_mutex); source = data->first_source; while (source) { struct obs_source *cur_source = obs_source_get_ref(source); - if (cur_source) - obs_source_video_tick(cur_source, seconds); + da_push_back(data->source_iteration_list, &cur_source); source = (struct obs_source *)source->context.next; - - if (cur_source) - obs_source_release(cur_source); } pthread_mutex_unlock(&data->sources_mutex); + /* obs_source_release should not be called while iterating through + * the global sources linked list, otherwise the linked list will + * be compromised */ + for (size_t i = 0; i < data->source_iteration_list.num; i++) { + struct obs_source *source = + data->source_iteration_list.array[i]; + obs_source_video_tick(source, seconds); + obs_source_release(source); + } + return cur_time; } diff --git a/libobs/obs.c b/libobs/obs.c index 2a8fbc7e1..7c634bb77 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -696,6 +696,7 @@ static void obs_free_data(void) pthread_mutex_destroy(&data->draw_callbacks_mutex); da_free(data->draw_callbacks); da_free(data->tick_callbacks); + da_free(data->source_iteration_list); obs_data_release(data->private_data); }