From 99deb0821fc0530cc9b05df7908a3ed397fc7967 Mon Sep 17 00:00:00 2001 From: Palana Date: Mon, 4 May 2015 01:37:14 +0200 Subject: [PATCH] libobs: Add refcounting helpers --- libobs/obs-internal.h | 42 ++++++++++++++++++++++++++++++++++++++++++ libobs/obs.c | 17 ++++++++++++----- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 4e949cf6d..4b360c564 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -275,6 +275,48 @@ extern void obs_context_data_setname(struct obs_context_data *context, const char *name); +/* ------------------------------------------------------------------------- */ +/* ref-counting */ + +struct obs_weak_ref { + volatile long refs; + volatile long weak_refs; +}; + +static inline void obs_ref_addref(struct obs_weak_ref *ref) +{ + os_atomic_inc_long(&ref->refs); +} + +static inline bool obs_ref_release(struct obs_weak_ref *ref) +{ + return os_atomic_dec_long(&ref->refs) == -1; +} + +static inline void obs_weak_ref_addref(struct obs_weak_ref *ref) +{ + os_atomic_inc_long(&ref->weak_refs); +} + +static inline bool obs_weak_ref_release(struct obs_weak_ref *ref) +{ + return os_atomic_dec_long(&ref->weak_refs) == -1; +} + +static inline bool obs_weak_ref_get_ref(struct obs_weak_ref *ref) +{ + long owners = ref->refs; + while (owners > -1) { + if (os_atomic_compare_swap_long(&ref->refs, owners, owners + 1)) + return true; + + owners = ref->refs; + } + + return false; +} + + /* ------------------------------------------------------------------------- */ /* sources */ diff --git a/libobs/obs.c b/libobs/obs.c index 9d5d8fe87..eeb0febfe 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -1164,7 +1164,7 @@ obs_source_t *obs_get_source_by_name(const char *name) } static inline void *get_context_by_name(void *vfirst, const char *name, - pthread_mutex_t *mutex) + pthread_mutex_t *mutex, void *(*addref)(void*)) { struct obs_context_data **first = vfirst; struct obs_context_data *context; @@ -1173,8 +1173,10 @@ static inline void *get_context_by_name(void *vfirst, const char *name, context = *first; while (context) { - if (strcmp(context->name, name) == 0) + if (strcmp(context->name, name) == 0) { + context = addref(context); break; + } context = context->next; } @@ -1182,25 +1184,30 @@ static inline void *get_context_by_name(void *vfirst, const char *name, return context; } +static inline void *obs_id_(void *data) +{ + return data; +} + obs_output_t *obs_get_output_by_name(const char *name) { if (!obs) return NULL; return get_context_by_name(&obs->data.first_output, name, - &obs->data.outputs_mutex); + &obs->data.outputs_mutex, obs_id_); } obs_encoder_t *obs_get_encoder_by_name(const char *name) { if (!obs) return NULL; return get_context_by_name(&obs->data.first_encoder, name, - &obs->data.encoders_mutex); + &obs->data.encoders_mutex, obs_id_); } obs_service_t *obs_get_service_by_name(const char *name) { if (!obs) return NULL; return get_context_by_name(&obs->data.first_service, name, - &obs->data.services_mutex); + &obs->data.services_mutex, obs_id_); } gs_effect_t *obs_get_default_effect(void) -- GitLab