mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-04 10:33:30 +00:00
libobs/callback: Make proc_handler_t threadsafe
Add mutexes to protect against multi-threaded memory access violations.
This commit is contained in:
parent
c46a719c9c
commit
23cda97a54
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "../util/darray.h"
|
||||
#include "../util/threading.h"
|
||||
|
||||
#include "decl.h"
|
||||
#include "proc.h"
|
||||
|
@ -32,24 +33,50 @@ static inline void proc_info_free(struct proc_info *pi)
|
|||
|
||||
struct proc_handler {
|
||||
/* TODO: replace with hash table lookup? */
|
||||
pthread_mutex_t mutex;
|
||||
DARRAY(struct proc_info) procs;
|
||||
};
|
||||
|
||||
static struct proc_info *getproc(proc_handler_t *handler, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < handler->procs.num; i++) {
|
||||
struct proc_info *info = handler->procs.array + i;
|
||||
|
||||
if (strcmp(info->func.name, name) == 0) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
proc_handler_t *proc_handler_create(void)
|
||||
{
|
||||
struct proc_handler *handler = bmalloc(sizeof(struct proc_handler));
|
||||
|
||||
if (pthread_mutex_init_recursive(&handler->mutex) != 0) {
|
||||
blog(LOG_ERROR, "Couldn't create proc_handler mutex");
|
||||
bfree(handler);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
da_init(handler->procs);
|
||||
return handler;
|
||||
}
|
||||
|
||||
void proc_handler_destroy(proc_handler_t *handler)
|
||||
{
|
||||
if (handler) {
|
||||
for (size_t i = 0; i < handler->procs.num; i++)
|
||||
proc_info_free(handler->procs.array + i);
|
||||
da_free(handler->procs);
|
||||
bfree(handler);
|
||||
}
|
||||
if (!handler)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < handler->procs.num; i++)
|
||||
proc_info_free(handler->procs.array + i);
|
||||
|
||||
da_free(handler->procs);
|
||||
pthread_mutex_destroy(&handler->mutex);
|
||||
bfree(handler);
|
||||
}
|
||||
|
||||
void proc_handler_add(proc_handler_t *handler, const char *decl_string,
|
||||
|
@ -70,7 +97,18 @@ void proc_handler_add(proc_handler_t *handler, const char *decl_string,
|
|||
pi.callback = proc;
|
||||
pi.data = data;
|
||||
|
||||
da_push_back(handler->procs, &pi);
|
||||
pthread_mutex_lock(&handler->mutex);
|
||||
|
||||
struct proc_info *existing = getproc(handler, pi.func.name);
|
||||
if (existing) {
|
||||
blog(LOG_WARNING, "Procedure '%s' already exists",
|
||||
pi.func.name);
|
||||
proc_info_free(&pi);
|
||||
} else {
|
||||
da_push_back(handler->procs, &pi);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&handler->mutex);
|
||||
}
|
||||
|
||||
bool proc_handler_call(proc_handler_t *handler, const char *name,
|
||||
|
@ -79,14 +117,16 @@ bool proc_handler_call(proc_handler_t *handler, const char *name,
|
|||
if (!handler)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < handler->procs.num; i++) {
|
||||
struct proc_info *info = handler->procs.array + i;
|
||||
pthread_mutex_lock(&handler->mutex);
|
||||
struct proc_info *info = getproc(handler, name);
|
||||
struct proc_info info_copy;
|
||||
if (info)
|
||||
info_copy = *info;
|
||||
pthread_mutex_unlock(&handler->mutex);
|
||||
|
||||
if (strcmp(info->func.name, name) == 0) {
|
||||
info->callback(info->data, params);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
info_copy.callback(info_copy.data, params);
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue