From 87475cdf89b4af0008643385ea71d1d8dd614aac Mon Sep 17 00:00:00 2001 From: jp9000 Date: Wed, 2 Jul 2014 20:58:30 -0700 Subject: [PATCH] Add rename cache for thread safety This just ensures that if an obs object is renamed that the pointer to older names will still be valid. Prevents renames from causing any invalid memory access. When the obs object is destroyed, so are the cached names. --- libobs/obs-internal.h | 3 +++ libobs/obs.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 28e055742..61da59ba3 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -198,6 +198,9 @@ struct obs_context_data { signal_handler_t signals; proc_handler_t procs; + DARRAY(char*) rename_cache; + pthread_mutex_t rename_cache_mutex; + pthread_mutex_t *mutex; struct obs_context_data *next; struct obs_context_data **prev_next; diff --git a/libobs/obs.c b/libobs/obs.c index 787dc5d1b..811fdef99 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -1189,8 +1189,12 @@ static inline bool obs_context_data_init_wrap( { assert(context); + pthread_mutex_init_value(&context->rename_cache_mutex); obs_context_data_free(context); + if (pthread_mutex_init(&context->rename_cache_mutex, NULL) < 0) + return false; + context->signals = signal_handler_create(); if (!context) return false; @@ -1201,6 +1205,8 @@ static inline bool obs_context_data_init_wrap( context->name = dup_name(name); context->settings = obs_data_newref(settings); + + da_init(context->rename_cache); return true; } @@ -1223,8 +1229,13 @@ void obs_context_data_free(struct obs_context_data *context) proc_handler_destroy(context->procs); obs_data_release(context->settings); obs_context_data_remove(context); + pthread_mutex_destroy(&context->rename_cache_mutex); bfree(context->name); + for (size_t i = 0; i < context->rename_cache.num; i++) + bfree(context->rename_cache.array[i]); + da_free(context->rename_cache); + memset(context, 0, sizeof(*context)); } @@ -1264,6 +1275,11 @@ void obs_context_data_remove(struct obs_context_data *context) void obs_context_data_setname(struct obs_context_data *context, const char *name) { - bfree(context->name); + pthread_mutex_lock(&context->rename_cache_mutex); + + if (context->name) + da_push_back(context->rename_cache, &context->name); context->name = dup_name(name); + + pthread_mutex_unlock(&context->rename_cache_mutex); }