diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index 676be6d65..9d18a6893 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include #include @@ -285,12 +286,12 @@ struct gs_sampler_state { static inline void samplerstate_addref(samplerstate_t ss) { - ss->ref++; + os_atomic_inc_long(&ss->ref); } static inline void samplerstate_release(samplerstate_t ss) { - if (--ss->ref == 0) + if (os_atomic_dec_long(&ss->ref) == 0) bfree(ss); } diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index 35ee06168..4bea457c4 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -241,5 +241,5 @@ struct graphics_subsystem { DARRAY(struct vec2) texverts[16]; pthread_mutex_t mutex; - volatile int ref; + volatile long ref; }; diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 5b5de8969..46f512a10 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -179,13 +179,13 @@ void gs_entercontext(graphics_t graphics) thread_graphics = graphics; } - graphics->ref++; + os_atomic_inc_long(&graphics->ref); } void gs_leavecontext(void) { if (thread_graphics) { - if (!--thread_graphics->ref) { + if (!os_atomic_dec_long(&thread_graphics->ref)) { graphics_t graphics = thread_graphics; graphics->exports.device_leavecontext(graphics->device); diff --git a/libobs/obs-data.c b/libobs/obs-data.c index dc99f3cf1..b3c25e3fe 100644 --- a/libobs/obs-data.c +++ b/libobs/obs-data.c @@ -16,11 +16,12 @@ ******************************************************************************/ #include "util/bmem.h" +#include "util/threading.h" #include "util/darray.h" #include "obs-data.h" struct obs_data_item { - volatile int ref; + volatile long ref; struct obs_data *parent; struct obs_data_item *next; enum obs_data_type type; @@ -30,13 +31,13 @@ struct obs_data_item { }; struct obs_data { - volatile int ref; + volatile long ref; char *json; struct obs_data_item *first_item; }; struct obs_data_array { - volatile int ref; + volatile long ref; DARRAY(obs_data_t) objects; }; @@ -244,7 +245,7 @@ obs_data_t obs_data_create_from_json(const char *json_string) void obs_data_addref(obs_data_t data) { if (data) - ++data->ref; + os_atomic_inc_long(&data->ref); } static inline void obs_data_destroy(struct obs_data *data) @@ -265,7 +266,7 @@ void obs_data_release(obs_data_t data) { if (!data) return; - if (--data->ref == 0) + if (os_atomic_dec_long(&data->ref) == 0) obs_data_destroy(data); } @@ -466,7 +467,7 @@ obs_data_t obs_data_getobj(obs_data_t data, const char *name) obs_data_t obj = get_item_obj(item); if (obj) - obj->ref++; + os_atomic_inc_long(&obj->ref); return obj; } @@ -476,7 +477,7 @@ obs_data_array_t obs_data_getarray(obs_data_t data, const char *name) obs_data_array_t array = get_item_array(item); if (array) - array->ref++; + os_atomic_inc_long(&array->ref); return array; } @@ -491,7 +492,7 @@ obs_data_array_t obs_data_array_create() void obs_data_array_addref(obs_data_array_t array) { if (array) - ++array->ref; + os_atomic_inc_long(&array->ref); } static inline void obs_data_array_destroy(obs_data_array_t array) @@ -509,7 +510,7 @@ void obs_data_array_release(obs_data_array_t array) if (!array) return; - if (--array->ref == 0) + if (os_atomic_dec_long(&array->ref) == 0) obs_data_array_destroy(array); } @@ -528,7 +529,7 @@ obs_data_t obs_data_array_item(obs_data_array_t array, size_t idx) data = (idx < array->objects.num) ? array->objects.array[idx] : NULL; if (data) - data->ref++; + os_atomic_inc_long(&data->ref); return data; } @@ -537,7 +538,7 @@ size_t obs_data_array_push_back(obs_data_array_t array, obs_data_t obj) if (!array || !obj) return 0; - obj->ref++; + os_atomic_inc_long(&obj->ref); return da_push_back(array->objects, &obj); } @@ -546,7 +547,7 @@ void obs_data_array_insert(obs_data_array_t array, size_t idx, obs_data_t obj) if (!array || !obj) return; - obj->ref++; + os_atomic_inc_long(&obj->ref); da_insert(array->objects, idx, &obj); } @@ -567,7 +568,7 @@ obs_data_item_t obs_data_first(obs_data_t data) return NULL; if (data->first_item) - data->first_item->ref++; + os_atomic_inc_long(&data->first_item->ref); return data->first_item; } @@ -578,18 +579,20 @@ obs_data_item_t obs_data_item_byname(obs_data_t data, const char *name) struct obs_data_item *item = get_item(data, name); if (item) - item->ref++; + os_atomic_inc_long(&item->ref); return item; } bool obs_data_item_next(obs_data_item_t *item) { if (item && *item) { - (*item)->ref--; - *item = (*item)->next; + obs_data_item_t next = (*item)->next; + obs_data_item_release(item); - if (*item) { - (*item)->ref++; + *item = next; + + if (next) { + os_atomic_inc_long(&next->ref); return true; } } @@ -600,7 +603,7 @@ bool obs_data_item_next(obs_data_item_t *item) void obs_data_item_release(obs_data_item_t *item) { if (item && *item) { - int ref = --(*item)->ref; + long ref = os_atomic_dec_long(&(*item)->ref); if (!ref) { obs_data_item_destroy(*item); *item = NULL; @@ -689,7 +692,7 @@ obs_data_t obs_data_item_getobj(obs_data_item_t item) get_item_obj(item) : NULL; if (obj) - obj->ref++; + os_atomic_inc_long(&obj->ref); return obj; } @@ -699,6 +702,6 @@ obs_data_array_t obs_data_item_getarray(obs_data_item_t item) get_item_array(item) : NULL; if (array) - array->ref++; + os_atomic_inc_long(&array->ref); return array; } diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index b0f87fafa..3c26e1b96 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -176,7 +176,7 @@ extern void *obs_video_thread(void *param); /* sources */ struct obs_source { - volatile int refs; + volatile long refs; struct obs_source_info info; /* source-specific data */ @@ -188,13 +188,13 @@ struct obs_source { proc_handler_t procs; /* ensures show/hide are only called once */ - int show_refs; + volatile long show_refs; /* ensures activate/deactivate are only called once */ - int activate_refs; + volatile long activate_refs; /* prevents infinite recursion when enumerating sources */ - int enum_refs; + volatile long enum_refs; /* used to indicate that the source has been removed and all * references to it should be released (not exactly how I would prefer @@ -204,7 +204,7 @@ struct obs_source { /* timing (if video is present, is based upon video) */ volatile bool timing_set; volatile uint64_t timing_adjust; - volatile int audio_reset_ref; + volatile long audio_reset_ref; uint64_t next_audio_ts_min; uint64_t last_frame_ts; uint64_t last_sys_timestamp; diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 7697ba8ab..fbe31870e 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -15,6 +15,7 @@ along with this program. If not, see . ******************************************************************************/ +#include "util/threading.h" #include "graphics/math-defs.h" #include "obs-scene.h" @@ -373,7 +374,7 @@ static void obs_sceneitem_destroy(obs_sceneitem_t item) void obs_sceneitem_addref(obs_sceneitem_t item) { if (item) - ++item->ref; + os_atomic_inc_long(&item->ref); } void obs_sceneitem_release(obs_sceneitem_t item) @@ -381,7 +382,7 @@ void obs_sceneitem_release(obs_sceneitem_t item) if (!item) return; - if (--item->ref == 0) + if (os_atomic_dec_long(&item->ref) == 0) obs_sceneitem_destroy(item); } diff --git a/libobs/obs-scene.h b/libobs/obs-scene.h index 776837af3..5451a7f91 100644 --- a/libobs/obs-scene.h +++ b/libobs/obs-scene.h @@ -23,7 +23,7 @@ /* how obs scene! */ struct obs_scene_item { - volatile int ref; + volatile long ref; volatile bool removed; struct obs_scene *parent; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index dd5331362..83f1096f6 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -19,6 +19,7 @@ #include "media-io/format-conversion.h" #include "media-io/video-frame.h" +#include "util/threading.h" #include "util/platform.h" #include "callback/calldata.h" #include "graphics/matrix3.h" @@ -268,7 +269,7 @@ static void obs_source_destroy(struct obs_source *source) void obs_source_addref(obs_source_t source) { if (source) - ++source->refs; + os_atomic_inc_long(&source->refs); } void obs_source_release(obs_source_t source) @@ -276,7 +277,7 @@ void obs_source_release(obs_source_t source) if (!source) return; - if (--source->refs == 0) + if (os_atomic_dec_long(&source->refs) == 0) obs_source_destroy(source); } @@ -380,7 +381,7 @@ static void hide_source(obs_source_t source) static void activate_tree(obs_source_t parent, obs_source_t child, void *param) { - if (++child->activate_refs == 1) + if (os_atomic_inc_long(&child->activate_refs) == 1) activate_source(child); UNUSED_PARAMETER(parent); @@ -390,7 +391,7 @@ static void activate_tree(obs_source_t parent, obs_source_t child, void *param) static void deactivate_tree(obs_source_t parent, obs_source_t child, void *param) { - if (--child->activate_refs == 0) + if (os_atomic_dec_long(&child->activate_refs) == 0) deactivate_source(child); UNUSED_PARAMETER(parent); @@ -399,7 +400,7 @@ static void deactivate_tree(obs_source_t parent, obs_source_t child, static void show_tree(obs_source_t parent, obs_source_t child, void *param) { - if (++child->show_refs == 1) + if (os_atomic_inc_long(&child->show_refs) == 1) show_source(child); UNUSED_PARAMETER(parent); @@ -408,7 +409,7 @@ static void show_tree(obs_source_t parent, obs_source_t child, void *param) static void hide_tree(obs_source_t parent, obs_source_t child, void *param) { - if (--child->show_refs == 0) + if (os_atomic_dec_long(&child->show_refs) == 0) hide_source(child); UNUSED_PARAMETER(parent); @@ -419,13 +420,13 @@ void obs_source_activate(obs_source_t source, enum view_type type) { if (!source) return; - if (++source->show_refs == 1) { + if (os_atomic_inc_long(&source->show_refs) == 1) { show_source(source); obs_source_enum_tree(source, show_tree, NULL); } if (type == MAIN_VIEW) { - if (++source->activate_refs == 1) { + if (os_atomic_inc_long(&source->activate_refs) == 1) { activate_source(source); obs_source_enum_tree(source, activate_tree, NULL); obs_source_set_present_volume(source, 1.0f); @@ -437,13 +438,13 @@ void obs_source_deactivate(obs_source_t source, enum view_type type) { if (!source) return; - if (--source->show_refs == 0) { + if (os_atomic_dec_long(&source->show_refs) == 0) { hide_source(source); obs_source_enum_tree(source, hide_tree, NULL); } if (type == MAIN_VIEW) { - if (--source->activate_refs == 0) { + if (os_atomic_dec_long(&source->activate_refs) == 0) { deactivate_source(source); obs_source_enum_tree(source, deactivate_tree, NULL); obs_source_set_present_volume(source, 0.0f); @@ -496,7 +497,7 @@ static inline void handle_ts_jump(obs_source_t source, uint64_t expected, /* if has video, ignore audio data until reset */ if (source->info.output_flags & OBS_SOURCE_ASYNC_VIDEO) - source->audio_reset_ref--; + os_atomic_dec_long(&source->audio_reset_ref); else reset_audio_timing(source, ts); } @@ -1384,12 +1385,12 @@ static void enum_source_tree_callback(obs_source_t parent, obs_source_t child, struct source_enum_data *data = param; if (child->info.enum_sources && !child->enum_refs) { - child->enum_refs++; + os_atomic_inc_long(&child->enum_refs); child->info.enum_sources(child->data, enum_source_tree_callback, data); - child->enum_refs--; + os_atomic_dec_long(&child->enum_refs); } data->enum_callback(parent, child, data->param); @@ -1404,9 +1405,9 @@ void obs_source_enum_sources(obs_source_t source, obs_source_addref(source); - source->enum_refs++; + os_atomic_inc_long(&source->enum_refs); source->info.enum_sources(source->data, enum_callback, param); - source->enum_refs--; + os_atomic_dec_long(&source->enum_refs); obs_source_release(source); } @@ -1422,10 +1423,10 @@ void obs_source_enum_tree(obs_source_t source, obs_source_addref(source); - source->enum_refs++; + os_atomic_inc_long(&source->enum_refs); source->info.enum_sources(source->data, enum_source_tree_callback, &data); - source->enum_refs--; + os_atomic_dec_long(&source->enum_refs); obs_source_release(source); } diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c index 21d7dd5cf..30586699d 100644 --- a/libobs/util/platform-nix.c +++ b/libobs/util/platform-nix.c @@ -116,13 +116,3 @@ int os_mkdir(const char *path) return (errno == EEXIST) ? MKDIR_EXISTS : MKDIR_ERROR; } - -long atomic_inc_long(volatile long *val) -{ - return __sync_fetch_and_add(val, 1); -} - -long atomic_dec_long(volatile long *val) -{ - return __sync_fetch_and_sub(val, 1); -} diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c index 3b30c4f4a..eda78408b 100644 --- a/libobs/util/platform-windows.c +++ b/libobs/util/platform-windows.c @@ -185,16 +185,6 @@ int os_mkdir(const char *path) return MKDIR_SUCCESS; } -long atomic_inc_long(volatile long *val) -{ - return InterlockedIncrement(val); -} - -long atomic_dec_long(volatile long *val) -{ - return InterlockedDecrement(val); -} - BOOL WINAPI DllMain(HINSTANCE hinst_dll, DWORD reason, LPVOID reserved) { diff --git a/libobs/util/platform.h b/libobs/util/platform.h index 48b36218e..846acb71e 100644 --- a/libobs/util/platform.h +++ b/libobs/util/platform.h @@ -76,9 +76,6 @@ EXPORT char *os_get_config_path(const char *name); EXPORT bool os_file_exists(const char *path); -EXPORT long atomic_inc_long(volatile long *val); -EXPORT long atomic_dec_long(volatile long *val); - #define MKDIR_EXISTS 1 #define MKDIR_SUCCESS 0 #define MKDIR_ERROR -1 diff --git a/libobs/util/threading-posix.c b/libobs/util/threading-posix.c index 70b450774..f3a0475f9 100644 --- a/libobs/util/threading-posix.c +++ b/libobs/util/threading-posix.c @@ -235,3 +235,13 @@ int os_sem_wait(os_sem_t sem) } #endif + +long os_atomic_inc_long(volatile long *val) +{ + return __sync_fetch_and_add(val, 1); +} + +long os_atomic_dec_long(volatile long *val) +{ + return __sync_fetch_and_sub(val, 1); +} diff --git a/libobs/util/threading-windows.c b/libobs/util/threading-windows.c index 6aff50da6..cce3b630f 100644 --- a/libobs/util/threading-windows.c +++ b/libobs/util/threading-windows.c @@ -150,3 +150,13 @@ int os_sem_wait(os_sem_t sem) ret = WaitForSingleObject(sem->handle, INFINITE); return (ret == WAIT_OBJECT_0) ? 0 : -1; } + +long os_atomic_inc_long(volatile long *val) +{ + return InterlockedIncrement(val); +} + +long os_atomic_dec_long(volatile long *val) +{ + return InterlockedDecrement(val); +} diff --git a/libobs/util/threading.h b/libobs/util/threading.h index 1ae17cdec..e525cf82f 100644 --- a/libobs/util/threading.h +++ b/libobs/util/threading.h @@ -67,6 +67,9 @@ EXPORT void os_sem_destroy(os_sem_t sem); EXPORT int os_sem_post(os_sem_t sem); EXPORT int os_sem_wait(os_sem_t sem); +EXPORT long os_atomic_inc_long(volatile long *val); +EXPORT long os_atomic_dec_long(volatile long *val); + #ifdef __cplusplus } diff --git a/plugins/win-capture/dc-capture.c b/plugins/win-capture/dc-capture.c index 534d0a09f..0065412aa 100644 --- a/plugins/win-capture/dc-capture.c +++ b/plugins/win-capture/dc-capture.c @@ -5,7 +5,7 @@ static inline void init_textures(struct dc_capture *capture) { - for (size_t i = 0; i < capture->num_textures; i++) { + for (int i = 0; i < capture->num_textures; i++) { if (capture->compatibility) capture->textures[i] = gs_create_texture( capture->width, capture->height, @@ -28,6 +28,8 @@ void dc_capture_init(struct dc_capture *capture, int x, int y, uint32_t width, uint32_t height, bool cursor, bool compatibility) { + memset(capture, 0, sizeof(struct dc_capture)); + capture->x = x; capture->y = y; capture->width = width; @@ -76,7 +78,7 @@ void dc_capture_free(struct dc_capture *capture) gs_entercontext(obs_graphics()); - for (size_t i = 0; i < capture->num_textures; i++) + for (int i = 0; i < capture->num_textures; i++) texture_destroy(capture->textures[i]); gs_leavecontext();