summaryrefslogtreecommitdiff
path: root/src/lib/notifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/notifier.c')
-rw-r--r--src/lib/notifier.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/src/lib/notifier.c b/src/lib/notifier.c
index 2c098f6f..45745b9a 100644
--- a/src/lib/notifier.c
+++ b/src/lib/notifier.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Notifier event system using callbacks
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -20,11 +20,14 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#define _POSIX_C_SOURCE 200112L
+
#include <ouroboros/errno.h>
#include <ouroboros/notifier.h>
#include <ouroboros/list.h>
+#include <ouroboros/utils.h>
+#include <ouroboros/pthread.h>
-#include <pthread.h>
#include <stdlib.h>
struct listener {
@@ -35,12 +38,12 @@ struct listener {
struct {
struct list_head listeners;
- pthread_mutex_t lock;
+ pthread_rwlock_t lock;
} notifier;
int notifier_init(void)
{
- if (pthread_mutex_init(&notifier.lock, NULL))
+ if (pthread_rwlock_init(&notifier.lock, NULL))
return -1;
list_head_init(&notifier.listeners);
@@ -53,7 +56,7 @@ void notifier_fini(void)
struct list_head * p;
struct list_head * h;
- pthread_mutex_lock(&notifier.lock);
+ pthread_rwlock_wrlock(&notifier.lock);
list_for_each_safe(p, h, &notifier.listeners) {
struct listener * l = list_entry(p, struct listener, next);
@@ -61,9 +64,9 @@ void notifier_fini(void)
free(l);
}
- pthread_mutex_unlock(&notifier.lock);
+ pthread_rwlock_unlock(&notifier.lock);
- pthread_mutex_destroy(&notifier.lock);
+ pthread_rwlock_destroy(&notifier.lock);
}
void notifier_event(int event,
@@ -71,14 +74,16 @@ void notifier_event(int event,
{
struct list_head * p;
- pthread_mutex_lock(&notifier.lock);
+ pthread_rwlock_rdlock(&notifier.lock);
+
+ pthread_cleanup_push(__cleanup_rwlock_unlock, &notifier.lock)
list_for_each(p, &notifier.listeners) {
struct listener * l = list_entry(p, struct listener, next);
l->callback(l->obj, event, o);
}
- pthread_mutex_unlock(&notifier.lock);
+ pthread_cleanup_pop(true);
}
int notifier_reg(notifier_fn_t callback,
@@ -87,19 +92,19 @@ int notifier_reg(notifier_fn_t callback,
struct listener * l;
struct list_head * p;
- pthread_mutex_lock(&notifier.lock);
+ pthread_rwlock_wrlock(&notifier.lock);
list_for_each(p, &notifier.listeners) {
struct listener * l = list_entry(p, struct listener, next);
if (l->callback == callback) {
- pthread_mutex_unlock(&notifier.lock);
+ pthread_rwlock_unlock(&notifier.lock);
return -EPERM;
}
}
l = malloc(sizeof(*l));
if (l == NULL) {
- pthread_mutex_unlock(&notifier.lock);
+ pthread_rwlock_unlock(&notifier.lock);
return -ENOMEM;
}
@@ -108,7 +113,7 @@ int notifier_reg(notifier_fn_t callback,
list_add_tail(&l->next, &notifier.listeners);
- pthread_mutex_unlock(&notifier.lock);
+ pthread_rwlock_unlock(&notifier.lock);
return 0;
}
@@ -118,7 +123,7 @@ void notifier_unreg(notifier_fn_t callback)
struct list_head * p;
struct list_head * h;
- pthread_mutex_lock(&notifier.lock);
+ pthread_rwlock_wrlock(&notifier.lock);
list_for_each_safe(p, h, &notifier.listeners) {
struct listener * l = list_entry(p, struct listener, next);
@@ -129,5 +134,5 @@ void notifier_unreg(notifier_fn_t callback)
}
}
- pthread_mutex_unlock(&notifier.lock);
+ pthread_rwlock_unlock(&notifier.lock);
}