提交 7fba736d 编写于 作者: J jp9000

libobs/util: Use a mutex with config files

上级 be09c52e
......@@ -18,6 +18,7 @@
#include <stdio.h>
#include <wchar.h>
#include "config-file.h"
#include "threading.h"
#include "platform.h"
#include "base.h"
#include "bmem.h"
......@@ -57,8 +58,19 @@ struct config_data {
char *file;
struct darray sections; /* struct config_section */
struct darray defaults; /* struct config_section */
pthread_mutex_t mutex;
};
static inline bool init_mutex(config_t *config)
{
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0)
return false;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
return false;
return pthread_mutex_init(&config->mutex, &attr) == 0;
}
config_t *config_create(const char *file)
{
struct config_data *config;
......@@ -70,6 +82,12 @@ config_t *config_create(const char *file)
fclose(f);
config = bzalloc(sizeof(struct config_data));
if (!init_mutex(config)) {
bfree(config);
return NULL;
}
config->file = bstrdup(file);
return config;
}
......@@ -278,6 +296,11 @@ int config_open(config_t **config, const char *file,
if (!*config)
return CONFIG_ERROR;
if (!init_mutex(*config)) {
bfree(*config);
return CONFIG_ERROR;
}
(*config)->file = bstrdup(file);
errorcode = config_parse_file(&(*config)->sections, file, always_open);
......@@ -301,6 +324,11 @@ int config_open_string(config_t **config, const char *str)
if (!*config)
return CONFIG_ERROR;
if (!init_mutex(*config)) {
bfree(*config);
return CONFIG_ERROR;
}
(*config)->file = NULL;
lexer_init(&lex);
......@@ -333,9 +361,13 @@ int config_save(config_t *config)
dstr_init(&str);
dstr_init(&tmp);
pthread_mutex_lock(&config->mutex);
f = os_fopen(config->file, "wb");
if (!f)
if (!f) {
pthread_mutex_unlock(&config->mutex);
return CONFIG_FILENOTFOUND;
}
for (i = 0; i < config->sections.num; i++) {
struct config_section *section = darray_item(
......@@ -371,6 +403,8 @@ int config_save(config_t *config)
fwrite(str.array, 1, str.len, f);
fclose(f);
pthread_mutex_unlock(&config->mutex);
dstr_free(&tmp);
dstr_free(&str);
......@@ -391,6 +425,8 @@ int config_save_safe(config_t *config, const char *temp_ext,
return CONFIG_ERROR;
}
pthread_mutex_lock(&config->mutex);
dstr_copy(&temp_file, config->file);
if (*temp_ext != '.')
dstr_cat(&temp_file, ".");
......@@ -419,6 +455,7 @@ int config_save_safe(config_t *config, const char *temp_ext,
os_rename(temp_file.array, file);
cleanup:
pthread_mutex_unlock(&config->mutex);
dstr_free(&temp_file);
dstr_free(&backup_file);
return ret;
......@@ -442,6 +479,7 @@ void config_close(config_t *config)
darray_free(&config->defaults);
darray_free(&config->sections);
bfree(config->file);
pthread_mutex_destroy(&config->mutex);
bfree(config);
}
......@@ -453,14 +491,20 @@ size_t config_num_sections(config_t *config)
const char *config_get_section(config_t *config, size_t idx)
{
struct config_section *section;
const char *name = NULL;
pthread_mutex_lock(&config->mutex);
if (idx >= config->sections.num)
return NULL;
goto unlock;
section = darray_item(sizeof(struct config_section), &config->sections,
idx);
name = section->name;
return section->name;
unlock:
pthread_mutex_unlock(&config->mutex);
return name;
}
static const struct config_item *config_find_item(const struct darray *sections,
......@@ -487,14 +531,16 @@ static const struct config_item *config_find_item(const struct darray *sections,
return NULL;
}
static void config_set_item(struct darray *sections, const char *section,
const char *name, char *value)
static void config_set_item(config_t *config, struct darray *sections,
const char *section, const char *name, char *value)
{
struct config_section *sec = NULL;
struct config_section *array = sections->array;
struct config_item *item;
size_t i, j;
pthread_mutex_lock(&config->mutex);
for (i = 0; i < sections->num; i++) {
struct config_section *cur_sec = array+i;
struct config_item *items = cur_sec->items.array;
......@@ -506,7 +552,7 @@ static void config_set_item(struct darray *sections, const char *section,
if (astrcmpi(item->name, name) == 0) {
bfree(item->value);
item->value = value;
return;
goto unlock;
}
}
......@@ -524,6 +570,9 @@ static void config_set_item(struct darray *sections, const char *section,
item = darray_push_back_new(sizeof(struct config_item), &sec->items);
item->name = bstrdup(name);
item->value = value;
unlock:
pthread_mutex_unlock(&config->mutex);
}
void config_set_string(config_t *config, const char *section,
......@@ -531,7 +580,8 @@ void config_set_string(config_t *config, const char *section,
{
if (!value)
value = "";
config_set_item(&config->sections, section, name, bstrdup(value));
config_set_item(config, &config->sections, section, name,
bstrdup(value));
}
void config_set_int(config_t *config, const char *section,
......@@ -540,7 +590,7 @@ void config_set_int(config_t *config, const char *section,
struct dstr str;
dstr_init(&str);
dstr_printf(&str, "%"PRId64, value);
config_set_item(&config->sections, section, name, str.array);
config_set_item(config, &config->sections, section, name, str.array);
}
void config_set_uint(config_t *config, const char *section,
......@@ -549,14 +599,14 @@ void config_set_uint(config_t *config, const char *section,
struct dstr str;
dstr_init(&str);
dstr_printf(&str, "%"PRIu64, value);
config_set_item(&config->sections, section, name, str.array);
config_set_item(config, &config->sections, section, name, str.array);
}
void config_set_bool(config_t *config, const char *section,
const char *name, bool value)
{
char *str = bstrdup(value ? "true" : "false");
config_set_item(&config->sections, section, name, str);
config_set_item(config, &config->sections, section, name, str);
}
void config_set_double(config_t *config, const char *section,
......@@ -564,7 +614,7 @@ void config_set_double(config_t *config, const char *section,
{
char *str = bzalloc(64);
os_dtostr(value, str, 64);
config_set_item(&config->sections, section, name, str);
config_set_item(config, &config->sections, section, name, str);
}
void config_set_default_string(config_t *config, const char *section,
......@@ -572,7 +622,8 @@ void config_set_default_string(config_t *config, const char *section,
{
if (!value)
value = "";
config_set_item(&config->defaults, section, name, bstrdup(value));
config_set_item(config, &config->defaults, section, name,
bstrdup(value));
}
void config_set_default_int(config_t *config, const char *section,
......@@ -581,7 +632,7 @@ void config_set_default_int(config_t *config, const char *section,
struct dstr str;
dstr_init(&str);
dstr_printf(&str, "%"PRId64, value);
config_set_item(&config->defaults, section, name, str.array);
config_set_item(config, &config->defaults, section, name, str.array);
}
void config_set_default_uint(config_t *config, const char *section,
......@@ -590,14 +641,14 @@ void config_set_default_uint(config_t *config, const char *section,
struct dstr str;
dstr_init(&str);
dstr_printf(&str, "%"PRIu64, value);
config_set_item(&config->defaults, section, name, str.array);
config_set_item(config, &config->defaults, section, name, str.array);
}
void config_set_default_bool(config_t *config, const char *section,
const char *name, bool value)
{
char *str = bstrdup(value ? "true" : "false");
config_set_item(&config->defaults, section, name, str);
config_set_item(config, &config->defaults, section, name, str);
}
void config_set_default_double(config_t *config, const char *section,
......@@ -606,20 +657,25 @@ void config_set_default_double(config_t *config, const char *section,
struct dstr str;
dstr_init(&str);
dstr_printf(&str, "%g", value);
config_set_item(&config->defaults, section, name, str.array);
config_set_item(config, &config->defaults, section, name, str.array);
}
const char *config_get_string(const config_t *config, const char *section,
const char *config_get_string(config_t *config, const char *section,
const char *name)
{
const struct config_item *item = config_find_item(&config->sections,
section, name);
const struct config_item *item;
const char *value = NULL;
pthread_mutex_lock(&config->mutex);
item = config_find_item(&config->sections, section, name);
if (!item)
item = config_find_item(&config->defaults, section, name);
if (!item)
return NULL;
if (item)
value = item->value;
return item->value;
pthread_mutex_unlock(&config->mutex);
return value;
}
static inline int64_t str_to_int64(const char *str)
......@@ -644,7 +700,7 @@ static inline uint64_t str_to_uint64(const char *str)
return strtoull(str, NULL, 10);
}
int64_t config_get_int(const config_t *config, const char *section,
int64_t config_get_int(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_string(config, section, name);
......@@ -654,7 +710,7 @@ int64_t config_get_int(const config_t *config, const char *section,
return 0;
}
uint64_t config_get_uint(const config_t *config, const char *section,
uint64_t config_get_uint(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_string(config, section, name);
......@@ -664,7 +720,7 @@ uint64_t config_get_uint(const config_t *config, const char *section,
return 0;
}
bool config_get_bool(const config_t *config, const char *section,
bool config_get_bool(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_string(config, section, name);
......@@ -675,7 +731,7 @@ bool config_get_bool(const config_t *config, const char *section,
return false;
}
double config_get_double(const config_t *config, const char *section,
double config_get_double(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_string(config, section, name);
......@@ -689,6 +745,9 @@ bool config_remove_value(config_t *config, const char *section,
const char *name)
{
struct darray *sections = &config->sections;
bool success = false;
pthread_mutex_lock(&config->mutex);
for (size_t i = 0; i < sections->num; i++) {
struct config_section *sec = darray_item(
......@@ -706,27 +765,34 @@ bool config_remove_value(config_t *config, const char *section,
config_item_free(item);
darray_erase(sizeof(struct config_item),
&sec->items, j);
return true;
success = true;
goto unlock;
}
}
}
return false;
unlock:
pthread_mutex_unlock(&config->mutex);
return success;
}
const char *config_get_default_string(const config_t *config,
const char *config_get_default_string(config_t *config,
const char *section, const char *name)
{
const struct config_item *item;
const char *value = NULL;
pthread_mutex_lock(&config->mutex);
item = config_find_item(&config->defaults, section, name);
if (!item)
return NULL;
if (item)
value = item->value;
return item->value;
pthread_mutex_unlock(&config->mutex);
return value;
}
int64_t config_get_default_int(const config_t *config, const char *section,
int64_t config_get_default_int(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_default_string(config, section, name);
......@@ -736,7 +802,7 @@ int64_t config_get_default_int(const config_t *config, const char *section,
return 0;
}
uint64_t config_get_default_uint(const config_t *config, const char *section,
uint64_t config_get_default_uint(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_default_string(config, section, name);
......@@ -746,7 +812,7 @@ uint64_t config_get_default_uint(const config_t *config, const char *section,
return 0;
}
bool config_get_default_bool(const config_t *config, const char *section,
bool config_get_default_bool(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_default_string(config, section, name);
......@@ -757,7 +823,7 @@ bool config_get_default_bool(const config_t *config, const char *section,
return false;
}
double config_get_default_double(const config_t *config, const char *section,
double config_get_default_double(config_t *config, const char *section,
const char *name)
{
const char *value = config_get_default_string(config, section, name);
......@@ -767,15 +833,23 @@ double config_get_default_double(const config_t *config, const char *section,
return 0.0;
}
bool config_has_user_value(const config_t *config, const char *section,
bool config_has_user_value(config_t *config, const char *section,
const char *name)
{
return config_find_item(&config->sections, section, name) != NULL;
bool success;
pthread_mutex_lock(&config->mutex);
success = config_find_item(&config->sections, section, name) != NULL;
pthread_mutex_unlock(&config->mutex);
return success;
}
bool config_has_default_value(const config_t *config, const char *section,
bool config_has_default_value(config_t *config, const char *section,
const char *name)
{
return config_find_item(&config->defaults, section, name) != NULL;
bool success;
pthread_mutex_lock(&config->mutex);
success = config_find_item(&config->defaults, section, name) != NULL;
pthread_mutex_unlock(&config->mutex);
return success;
}
......@@ -64,15 +64,15 @@ EXPORT void config_set_bool(config_t *config, const char *section,
EXPORT void config_set_double(config_t *config, const char *section,
const char *name, double value);
EXPORT const char *config_get_string(const config_t *config,
EXPORT const char *config_get_string(config_t *config,
const char *section, const char *name);
EXPORT int64_t config_get_int(const config_t *config, const char *section,
EXPORT int64_t config_get_int(config_t *config, const char *section,
const char *name);
EXPORT uint64_t config_get_uint(const config_t *config, const char *section,
EXPORT uint64_t config_get_uint(config_t *config, const char *section,
const char *name);
EXPORT bool config_get_bool(const config_t *config, const char *section,
EXPORT bool config_get_bool(config_t *config, const char *section,
const char *name);
EXPORT double config_get_double(const config_t *config, const char *section,
EXPORT double config_get_double(config_t *config, const char *section,
const char *name);
EXPORT bool config_remove_value(config_t *config, const char *section,
......@@ -107,20 +107,20 @@ EXPORT void config_set_default_double(config_t *config, const char *section,
/* These functions allow you to get the current default values rather than get
* the actual values. Probably almost never really needed */
EXPORT const char *config_get_default_string(const config_t *config,
EXPORT const char *config_get_default_string(config_t *config,
const char *section, const char *name);
EXPORT int64_t config_get_default_int(const config_t *config,
EXPORT int64_t config_get_default_int(config_t *config,
const char *section, const char *name);
EXPORT uint64_t config_get_default_uint(const config_t *config,
EXPORT uint64_t config_get_default_uint(config_t *config,
const char *section, const char *name);
EXPORT bool config_get_default_bool(const config_t *config,
EXPORT bool config_get_default_bool(config_t *config,
const char *section, const char *name);
EXPORT double config_get_default_double(const config_t *config,
EXPORT double config_get_default_double(config_t *config,
const char *section, const char *name);
EXPORT bool config_has_user_value(const config_t *config,
EXPORT bool config_has_user_value(config_t *config,
const char *section, const char *name);
EXPORT bool config_has_default_value(const config_t *config,
EXPORT bool config_has_default_value(config_t *config,
const char *section, const char *name);
#ifdef __cplusplus
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册