]> git.lizzy.rs Git - dragonstd.git/commitdiff
Callback rework
authorElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 13 Apr 2022 18:13:43 +0000 (20:13 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 13 Apr 2022 18:13:43 +0000 (20:13 +0200)
16 files changed:
bits/callback.h
bits/wrappers.h
flag.c
list.c
list.h
map.c
map.h
queue.c
queue.h
refcount.c
refcount.h
test/test_list.c
test/test_refcount_map.c
test/test_tree.c
tree.c
tree.h

index 2c541d5f93fcf256dc6db2e5fadafe792b42ff40..5316492cfba344c528d0d5d48ab0a6640a02e2ad 100644 (file)
@@ -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_
index 9169053e0366ab6475e8a2ca6471d36a2408ab79..a2786791875e0c31a34dd664136b2d526330ddb4 100644 (file)
@@ -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 6937e5f04e3a1b58746d5eb7c54a1aefb8b8ccf7..e53154611dffbe4765c26c2c9673688929ea4b76 100644 (file)
--- 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 f7b3803fbacfb822c78b76c890a1ce198cd40ace..a4aba67a5772ffc89f52da814a32ea25424fc87b 100644 (file)
--- 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 94bacf2f591418328cf5e13cf811ae79adadca9d..7a9e904d92040722f8e6452ce05d7603aa50f96e 100644 (file)
--- a/list.h
+++ b/list.h
@@ -9,7 +9,7 @@
 #define _DRAGONSTD_LIST_H_
 
 #include <stdbool.h>       // 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 abdd7052ed7d36e77662899932d6b5a1389d47e3..491728025e7e6d0706f6dd3d340b2ae9588581e2 100644 (file)
--- 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 b74441caf714e9e368a14bced2fc6a7f6ca95a05..0c42ac8c4cc9463c55cc8f5851b6e2a9a0f1cfd0 100644 (file)
--- a/map.h
+++ b/map.h
@@ -11,7 +11,7 @@
 
 #include <stdbool.h>       // for bool
 #include <pthread.h>       // 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 606989c4ae79acc8fdd8c17c222bf0a253874aa6..91c2d314dd346e3db039593c17790fe880600220 100644 (file)
--- 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 dcfcd5f43206d378a614e862b28eaa27ffa20ca1..96fdcfc9d65e7ba10536e89d319b13564a4f87e0 100644 (file)
--- 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.
 
index dcb5b18565c390ac0028275b89b5a513694e8b2a..3b36ac7ca71812e65023d7e34f3b16b5e157dc09 100644 (file)
@@ -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;
 }
index f551b57c7ce47ef96e491cdd17cb26e92372cd94..0efab562d2bc80207a4a87c9ea47940f2c22a072 100644 (file)
 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_
index 18c5cf4a78da8a0d509175344f034e52900b0e60..baa5d91bd1324b683f7ccba47aa3a71678b8acb1 100644 (file)
@@ -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");
index 8e951f8ce478022969394eba58ecaeb47682f90b..bb369a26b3a10bde7edde2408a7d7f18109bc62a 100644 (file)
@@ -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)++;
        }
 
index 7267162c60be4dca4357822c6749429fd203afbf..b7e139121e2b1e6388118f191d5dd2596f82d601 100644 (file)
@@ -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 60c73ccb1eb7ee8020faa4ccecfd7a5a379dbfe8..42ac27702af795564bf984a396253f8d3ffe3aba 100644 (file)
--- 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 4df0e016e30e0de2ea6c7da1001dab5e26ed6d6d..a55671f3dd5481272bb04b97591a0736f7f7bd62 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -15,7 +15,7 @@
 #define _DRAGONSTD_TREE_H_
 
 #include <stdbool.h>       // 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.