From cf06b3bbba9ff3c9e565c3eb95136b07db135c13 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 13 Apr 2022 20:13:43 +0200 Subject: [PATCH] Callback rework --- bits/callback.h | 4 ++-- bits/wrappers.h | 4 ++-- flag.c | 2 +- list.c | 4 ++-- list.h | 8 +++---- map.c | 45 ++++++++++++++++++++++++++-------------- map.h | 8 +++---- queue.c | 2 +- queue.h | 2 +- refcount.c | 32 +++++++++++++--------------- refcount.h | 18 ++++++---------- test/test_list.c | 2 +- test/test_refcount_map.c | 6 +++--- test/test_tree.c | 2 +- tree.c | 6 +++--- tree.h | 8 +++---- 16 files changed, 79 insertions(+), 74 deletions(-) diff --git a/bits/callback.h b/bits/callback.h index 2c541d5..5316492 100644 --- a/bits/callback.h +++ b/bits/callback.h @@ -1,9 +1,9 @@ #ifndef _DRAGONSTD_CALLBACK_H_ // include guard #define _DRAGONSTD_CALLBACK_H_ +typedef void (*SingleCallback)(void *dat); +typedef void (*Callback)(void *dat, void *arg); typedef void *(*Transformer)(void *dat); -typedef void (*Callback)(void *dat); -typedef void (*Iterator)(void *dat, void *arg); typedef int (*Comparator)(const void *dat, const void *key); #endif // _DRAGONSTD_CALLBACK_H_ diff --git a/bits/wrappers.h b/bits/wrappers.h index 9169053..a278679 100644 --- a/bits/wrappers.h +++ b/bits/wrappers.h @@ -20,7 +20,7 @@ return trans ? trans((*node)->dat) : (*node)->dat; \ } \ \ - bool prefix ## del(Type *self, void *key, Comparator cmp, Callback call) \ + bool prefix ## del(Type *self, void *key, Comparator cmp, Callback call, void *arg) \ { \ Type ## Node **node = prefix ## nfd(self, key, cmp); \ \ @@ -28,7 +28,7 @@ return false; \ \ if (call) \ - call((*node)->dat); \ + call((*node)->dat, arg); \ \ prefix ## nrm(self, node); \ return true; \ diff --git a/flag.c b/flag.c index 6937e5f..e531546 100644 --- a/flag.c +++ b/flag.c @@ -26,7 +26,7 @@ void flag_sub(Flag *flag, pthread_cond_t *cnd) void flag_uns(Flag *flag, pthread_cond_t *cnd) { pthread_mutex_lock(&flag->mtx); - list_del(&flag->cvs, cnd, &cmp_ref, NULL); + list_del(&flag->cvs, cnd, &cmp_ref, NULL, NULL); pthread_mutex_unlock(&flag->mtx); } diff --git a/list.c b/list.c index f7b3803..a4aba67 100644 --- a/list.c +++ b/list.c @@ -57,13 +57,13 @@ void list_nrm(List *list, ListNode **node) free(old); } -void list_itr(List *list, Iterator iter, void *arg, Transformer trans) +void list_itr(List *list, Callback iter, void *arg, Transformer trans) { LIST_ITERATE(list, node) iter(trans ? trans(node->dat) : node->dat, arg); } -void list_clr(List *list, Iterator iter, void *arg, Transformer trans) +void list_clr(List *list, Callback iter, void *arg, Transformer trans) { for (ListNode *node = list->fst; node != NULL;) { ListNode *next = node->nxt; diff --git a/list.h b/list.h index 94bacf2..7a9e904 100644 --- a/list.h +++ b/list.h @@ -9,7 +9,7 @@ #define _DRAGONSTD_LIST_H_ #include // for bool -#include "bits/callback.h" // for Iterator, Comparator, Transformer, Callback +#include "bits/callback.h" // for Callback, Comparator, Transformer, Callback #include "bits/compare.h" // for cmp_ref (not used in file) #define LIST_ITERATE(list, node) for (ListNode *node = (list)->fst; node != NULL; node = node->nxt) @@ -50,7 +50,7 @@ void *list_get(List *list, void *key, Comparator cmp, Transformer trans); The first matching element is returned, or NULL if none found. */ -bool list_del(List *list, void *key, Comparator cmp, Callback call); +bool list_del(List *list, void *key, Comparator cmp, Callback call, void *arg); /* Delete an element from the list if it is found. Return whether an element has been deleted. @@ -86,7 +86,7 @@ void list_nrm(List *list, ListNode **node); Remove the node at the given location. */ -void list_itr(List *list, Iterator iter, void *arg, Transformer trans); +void list_itr(List *list, Callback iter, void *arg, Transformer trans); /* Iterate over the list. Calls iter on every element, with the extra argument arg. @@ -94,7 +94,7 @@ void list_itr(List *list, Iterator iter, void *arg, Transformer trans); Note: the LIST_ITERATE macro can be used to do this without function calls. */ -void list_clr(List *list, Iterator iter, void *arg, Transformer trans); +void list_clr(List *list, Callback iter, void *arg, Transformer trans); /* Iterates over the list and deletes all elements. Calls iter on every element, with the extra argument arg. diff --git a/map.c b/map.c index abdd705..4917280 100644 --- a/map.c +++ b/map.c @@ -32,7 +32,7 @@ void map_dst(Map *map) pthread_rwlock_destroy(&map->clk); } -void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order) +void map_cnl(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order) { pthread_rwlock_wrlock(&map->clk); map->cnl = true; @@ -45,22 +45,37 @@ void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversi pthread_rwlock_unlock(&map->tlk); } -#define WRAP_TREE_FUNC(type, name, write, CallbackType, null) \ - type map_ ## name(Map *map, void *dat, Comparator cmp, CallbackType func) \ - { \ - if (!get_lock(map, write)) \ - return null; \ - \ - type ret = tree_ ## name(&map->tre, dat, cmp, func); \ - pthread_rwlock_unlock(&map->tlk); \ - return ret; \ - } +bool map_add(Map *map, void *dat, Comparator cmp, Transformer trans) +{ + if (!get_lock(map, true)) + return false; + + bool ret = tree_add(&map->tre, dat, cmp, trans); + pthread_rwlock_unlock(&map->tlk); + return ret; +} + +void *map_get(Map *map, void *key, Comparator cmp, Transformer trans) +{ + if (!get_lock(map, false)) + return NULL; -WRAP_TREE_FUNC(bool, add, true, Transformer, false) -WRAP_TREE_FUNC(void *, get, false, Transformer, NULL) -WRAP_TREE_FUNC(bool, del, true, Callback, false) + void *ret = tree_get(&map->tre, key, cmp, trans); + pthread_rwlock_unlock(&map->tlk); + return ret; +} + +bool map_del(Map *map, void *key, Comparator cmp, Callback call, void *arg) +{ + if (!get_lock(map, true)) + return false; + + bool ret = tree_del(&map->tre, key, cmp, call, arg); + pthread_rwlock_unlock(&map->tlk); + return ret; +} -void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order) +void map_trv(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order) { if (!get_lock(map, false)) return; diff --git a/map.h b/map.h index b74441c..0c42ac8 100644 --- a/map.h +++ b/map.h @@ -11,7 +11,7 @@ #include // for bool #include // for pthread_rwlock_t -#include "bits/callback.h" // for Transformer, Comparator, Iterator +#include "bits/callback.h" // for Transformer, Comparator, Callback #include "tree.h" // for Tree typedef struct { @@ -38,7 +38,7 @@ void map_dst(Map *map); Make sure to cancel the map before destroying it, to avoid memory leaks. */ -void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order); +void map_cnl(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order); /* [Thread Safe] Cancels and clears the map. @@ -67,14 +67,14 @@ void *map_get(Map *map, void *key, Comparator cmp, Transformer trans); Get an element from the map, or return NULL if none found. */ -bool map_del(Map *map, void *key, Comparator cmp, Callback call); +bool map_del(Map *map, void *key, Comparator cmp, Callback call, void *arg); /* [Thread Safe] Delete an element from the map if it is found. Return whether an element has been deleted. */ -void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order); +void map_trv(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order); /* [Thread Safe] Traverse the map. diff --git a/queue.c b/queue.c index 606989c..91c2d31 100644 --- a/queue.c +++ b/queue.c @@ -15,7 +15,7 @@ void queue_dst(Queue *queue) pthread_mutex_destroy(&queue->mtx); } -void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans) +void queue_clr(Queue *queue, Callback iter, void *arg, Transformer trans) { list_clr(&queue->lst, iter, arg, trans); } diff --git a/queue.h b/queue.h index dcfcd5f..96fdcfc 100644 --- a/queue.h +++ b/queue.h @@ -40,7 +40,7 @@ void queue_dst(Queue *queue); list is cleared before calling this function. */ -void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans); +void queue_clr(Queue *queue, Callback iter, void *arg, Transformer trans); /* Clears the queue. diff --git a/refcount.c b/refcount.c index dcb5b18..3b36ac7 100644 --- a/refcount.c +++ b/refcount.c @@ -1,6 +1,6 @@ #include "refcount.h" -void refcount_ini(Refcount *refcount, void *obj, Callback del) +void refcount_ini(Refcount *refcount, void *obj, SingleCallback del) { refcount->obj = obj; refcount->del = del; @@ -13,34 +13,30 @@ void refcount_dst(Refcount *refcount) pthread_mutex_destroy(&refcount->mtx); } -void *refcount_inc(void *refcount) +void *refcount_inc(Refcount *refcount) { - Refcount *rc = refcount; - - pthread_mutex_lock(&rc->mtx); - rc->cnt++; - pthread_mutex_unlock(&rc->mtx); - return rc; + pthread_mutex_lock(&refcount->mtx); + refcount->cnt++; + pthread_mutex_unlock(&refcount->mtx); + return refcount; } -void *refcount_grb(void *refcount) +void *refcount_grb(Refcount *refcount) { return refcount_obj(refcount_inc(refcount)); } -void refcount_drp(void *refcount) +void refcount_drp(Refcount *refcount) { - Refcount *rc = refcount; - - pthread_mutex_lock(&rc->mtx); - unsigned short count = --rc->cnt; - pthread_mutex_unlock(&rc->mtx); + pthread_mutex_lock(&refcount->mtx); + unsigned short count = --refcount->cnt; + pthread_mutex_unlock(&refcount->mtx); if (!count) - rc->del(rc->obj); + refcount->del(refcount->obj); } -void *refcount_obj(void *refcount) +void *refcount_obj(Refcount *refcount) { - return ((Refcount *) refcount)->obj; + return refcount->obj; } diff --git a/refcount.h b/refcount.h index f551b57..0efab56 100644 --- a/refcount.h +++ b/refcount.h @@ -19,12 +19,12 @@ typedef struct { /* private */ void *obj; - Callback del; + SingleCallback del; unsigned short cnt; // counter pthread_mutex_t mtx; // lock to protect count } Refcount; -void refcount_ini(Refcount *refcount, void *obj, Callback del); +void refcount_ini(Refcount *refcount, void *obj, SingleCallback del); /* Initializes the refcount. @@ -43,39 +43,33 @@ void refcount_dst(Refcount *refcount); The refcount is unusable until reinitialized afterwards. */ -void *refcount_inc(void *refcount); +void *refcount_inc(Refcount *refcount); /* [Thread Safe] Grab a reference to the refcount. - This actually takes a Refcount * as argument, however void * is used to make it more - convenient to use the function as callback. Returns the refcount. */ -void *refcount_grb(void *refcount); +void *refcount_grb(Refcount *rc); /* [Thread Safe] Does the same as refcount_inc, except it returns the referenced object instead of the refcount. */ -void refcount_drp(void *refcount); +void refcount_drp(Refcount *refcount); /* [Thread Safe] Drop a reference to the object. - This actually takes a Refcount * as argument, however void * is used to make it more - convenient to use the function as callback. May delete the object using the del function if the counter gets down to zero. */ -void *refcount_obj(void *refcount); +void *refcount_obj(Refcount *refcount); /* [Thread Safe] Return referenced object. - This actually takes a Refcount * as argument, however void * is used to make it more - convenient to use the function as callback. */ #endif // _DRAGONSTD_REFCOUNT_H_ diff --git a/test/test_list.c b/test/test_list.c index 18c5cf4..baa5d91 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -38,7 +38,7 @@ int main() assert(list_get(&list, &e, &cmp_int, NULL) == NULL); printf("testing del\n"); - assert(list_del(&list, &a, &cmp_int, NULL)); + assert(list_del(&list, &a, &cmp_int, NULL, NULL)); assert(list_get(&list, &a, &cmp_int, NULL) == NULL); printf("testing clr\n"); diff --git a/test/test_refcount_map.c b/test/test_refcount_map.c index 8e951f8..bb369a2 100644 --- a/test/test_refcount_map.c +++ b/test/test_refcount_map.c @@ -49,7 +49,7 @@ static void *thread_create(unsigned int *result) refcount_ini(&obj->rc, obj, (void *) &data_object_delete); - if (map_add(&map, &obj->rc, &data_object_compare, &refcount_inc)) + if (map_add(&map, &obj->rc, &data_object_compare, (void *) &refcount_inc)) (*result)++; refcount_drp(&obj->rc); @@ -74,7 +74,7 @@ static void *thread_access(unsigned int *result) while (!objs[i] && !cancel) { int id = rand_id(); - objs[i] = map_get(&map, &id, &data_object_compare_id, &refcount_grb); + objs[i] = map_get(&map, &id, &data_object_compare_id, (void *) &refcount_grb); } if (objs[i]) @@ -95,7 +95,7 @@ static void *thread_delete(unsigned int *result) while (!cancel) { unsigned int id = rand_id(); - if (map_del(&map, &id, &data_object_compare_id, &refcount_drp)) + if (map_del(&map, &id, &data_object_compare_id, (void *) &refcount_drp, NULL)) (*result)++; } diff --git a/test/test_tree.c b/test/test_tree.c index 7267162..b7e1391 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -51,7 +51,7 @@ int main() assert(tree_get(&tree, &e, &cmp_int, NULL) == NULL); printf("testing del\n"); - assert(tree_del(&tree, &a, &cmp_int, NULL)); + assert(tree_del(&tree, &a, &cmp_int, NULL, NULL)); assert(tree_get(&tree, &a, &cmp_int, NULL) == NULL); printf("testing clr\n"); diff --git a/tree.c b/tree.c index 60c73cc..42ac277 100644 --- a/tree.c +++ b/tree.c @@ -17,7 +17,7 @@ static inline TreeNode **search(TreeNode **node, void *key, Comparator cmp) return search(&(*node)->rgt, key, cmp); } -static inline void traverse(TreeNode *node, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order, int delete) +static inline void traverse(TreeNode *node, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order, int delete) { if (!node) return; @@ -68,12 +68,12 @@ void tree_nrm(__attribute__((unused)) Tree *tree, TreeNode **node) free(old); } -void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order) +void tree_trv(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order) { traverse(tree->rot, iter, arg, trans, order, 0); } -void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order) +void tree_clr(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order) { traverse(tree->rot, iter, arg, trans, order, 1); tree_ini(tree); diff --git a/tree.h b/tree.h index 4df0e01..a55671f 100644 --- a/tree.h +++ b/tree.h @@ -15,7 +15,7 @@ #define _DRAGONSTD_TREE_H_ #include // for bool -#include "bits/callback.h" // for Iterator, Comparator, Transformer, Callback +#include "bits/callback.h" // for Callback, Comparator, Transformer, Callback #include "bits/compare.h" // for cmp_ref (not used in file) typedef struct TreeNode { @@ -58,7 +58,7 @@ void *tree_get(Tree *tree, void *key, Comparator cmp, Transformer trans); Get an element from the tree, or return NULL if none found. */ -bool tree_del(Tree *tree, void *key, Comparator cmp, Callback call); +bool tree_del(Tree *tree, void *key, Comparator cmp, Callback call, void *arg); /* Delete an element from the tree if it is found. Return whether an element has been deleted. @@ -82,13 +82,13 @@ void tree_nrm(Tree *tree, TreeNode **node); Remove the node at the given location. */ -void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order); +void tree_trv(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order); /* Traverse the tree. Calls iter on every element, with the extra argument arg. */ -void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order); +void tree_clr(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order); /* Traverses the tree and deletes all elements. Calls iter on every element, with the extra argument arg. -- 2.44.0