1
Fork 0

log: make pw_log_topic_register/unregister threadsafe

Make the topic registration/unregistration threadsafe, as they can be
called from constructors of static objects which don't necessarily run
in the main loop thread.
This commit is contained in:
Pauli Virtanen 2024-01-01 21:11:18 +02:00 committed by Wim Taymans
parent fb2d05aa61
commit 961d0cfdc1
2 changed files with 29 additions and 3 deletions

View File

@ -4,6 +4,7 @@
#include <limits.h>
#include <fnmatch.h>
#include <pthread.h>
#include <spa/support/log-impl.h>
@ -43,6 +44,8 @@ struct pattern {
static struct spa_list topics = SPA_LIST_INIT(&topics);
static struct spa_list patterns = SPA_LIST_INIT(&patterns);
static pthread_mutex_t topics_lock = PTHREAD_MUTEX_INITIALIZER;
PW_LOG_TOPIC(log_buffers, "pw.buffers");
PW_LOG_TOPIC(log_client, "pw.client");
PW_LOG_TOPIC(log_conf, "pw.conf");
@ -120,8 +123,12 @@ static void update_all_topic_levels(void)
{
struct topic *topic;
pthread_mutex_lock(&topics_lock);
spa_list_for_each(topic, &topics, link)
update_topic_level(topic->t);
pthread_mutex_unlock(&topics_lock);
}
SPA_EXPORT
@ -129,15 +136,20 @@ void pw_log_topic_register(struct spa_log_topic *t)
{
struct topic *topic;
pthread_mutex_lock(&topics_lock);
topic = find_topic(t);
if (!topic) {
update_topic_level(t);
topic = add_topic(t);
if (!topic)
return;
goto done;
}
++topic->refcnt;
done:
pthread_mutex_unlock(&topics_lock);
}
SPA_EXPORT
@ -145,14 +157,19 @@ void pw_log_topic_unregister(struct spa_log_topic *t)
{
struct topic *topic;
pthread_mutex_lock(&topics_lock);
topic = find_topic(t);
if (!topic)
return;
goto done;
if (topic->refcnt-- <= 1) {
spa_list_remove(&topic->link);
free(topic);
}
done:
pthread_mutex_unlock(&topics_lock);
}
void pw_log_topic_register_enum(const struct spa_log_topic_enum *e)
@ -313,6 +330,8 @@ int pw_log_set_level_string(const char *str)
pw_log_level = level;
global_log->level = level;
pthread_mutex_lock(&topics_lock);
spa_list_consume(pattern, &patterns, link) {
spa_list_remove(&pattern->link);
free(pattern);
@ -320,6 +339,8 @@ int pw_log_set_level_string(const char *str)
spa_list_insert_list(&patterns, &new_patterns);
pthread_mutex_unlock(&topics_lock);
update_all_topic_levels();
return 0;
}
@ -476,11 +497,15 @@ pw_log_deinit(void)
{
struct pattern *pattern;
pthread_mutex_lock(&topics_lock);
spa_list_consume(pattern, &patterns, link) {
spa_list_remove(&pattern->link);
free(pattern);
}
pthread_mutex_unlock(&topics_lock);
/* don't free log topics, since they usually won't get re-registered */
pw_log_set(NULL);

View File

@ -136,13 +136,14 @@ pw_log_logv(enum spa_log_level level,
* Register log topic with the logger, to enable dynamic log levels.
* Topic must be unregistered before freeing it or plugin unload.
* May be used instead of \ref PW_LOG_TOPIC_INIT
* This function is threadsafe.
*
* \since 1.1.0
*/
void pw_log_topic_register(struct spa_log_topic *t);
/**
* Unregister log topic
* Unregister log topic. This function is threadsafe.
*
* \since 1.1.0
*/