From 2f3a24d9065a5f7c86f0e0871f2ec45187561b20 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 28 Sep 2014 21:13:20 +0100 Subject: [PATCH] try to make code more thread save --- include/tr/hash.h | 20 ++++++++++---------- include/tr/tree.h | 10 +++++----- src/hash/each.c | 4 ++-- src/queue/destroy.c | 4 +++- src/queue/find.c | 4 ++++ src/queue/find_parent.c | 4 ++++ src/queue/put.c | 4 +++- src/queue/put_first.c | 4 +++- src/tree/delete.c | 4 +++- src/tree/destroy.c | 13 ++++++++++--- src/tree/find.c | 9 ++++++--- src/tree/insert.c | 12 ++++++++---- src/tree/walk.c | 21 +++++++++++++++++---- 13 files changed, 78 insertions(+), 35 deletions(-) diff --git a/include/tr/hash.h b/include/tr/hash.h index f95689c..9792d3d 100644 --- a/include/tr/hash.h +++ b/include/tr/hash.h @@ -37,16 +37,16 @@ TR_CLASS(TR_Hash) { TR_INSTANCE_INIT(TR_Hash); TR_CLASSVARS_DECL(TR_Hash) {}; -#define TR_hashEmpty(hash) (NULL == (hash)->tree->root) - -void * TR_hashAdd(TR_Hash, void *); -void * TR_hashDelete(TR_Hash, const char *, size_t); -void * TR_hashGet(TR_Hash, const char *, size_t); -void * TR_hashGetFirst(TR_Hash); -void * TR_hashDeleteByVal(TR_Hash, unsigned long); -void * TR_hashGetByVal(TR_Hash, unsigned long); -void TR_hashEach(TR_Hash, const void *, void (*)(const void *, const void *)); -void TR_hashCleanup(TR_Hash); +//#define TR_hashEmpty(hash) (NULL == (hash)->tree->root) + +void * TR_hashAdd(TR_Hash, void *); +void * TR_hashDelete(TR_Hash, const char *, size_t); +void * TR_hashGet(TR_Hash, const char *, size_t); +void * TR_hashGetFirst(TR_Hash); +void * TR_hashDeleteByVal(TR_Hash, unsigned long); +void * TR_hashGetByVal(TR_Hash, unsigned long); +unsigned long TR_hashEach(TR_Hash, const void *, void (*)(const void *, const void *)); +void TR_hashCleanup(TR_Hash); #endif // __TR_HASH_H__ diff --git a/include/tr/tree.h b/include/tr/tree.h index 67e761d..cb475b0 100644 --- a/include/tr/tree.h +++ b/include/tr/tree.h @@ -50,11 +50,11 @@ TR_CLASSVARS_DECL(TR_Tree) {}; typedef int (*TR_TreeComp)(const void *, const void *); typedef void (*TR_TreeAction)(const void *, const void *, const int); -void * TR_treeFind(TR_Tree, const void *, TR_TreeComp); -void * TR_treeInsert(TR_Tree, const void *, TR_TreeComp); -void * TR_treeDelete(TR_Tree, const void *, TR_TreeComp); -void TR_treeWalk(TR_Tree, const void *, TR_TreeAction); -void TR_treeDestroy(TR_Tree, TR_TreeAction); +void * TR_treeFind(TR_Tree, const void *, TR_TreeComp); +void * TR_treeInsert(TR_Tree, const void *, TR_TreeComp); +void * TR_treeDelete(TR_Tree, const void *, TR_TreeComp); +unsigned long TR_treeWalk(TR_Tree, const void *, TR_TreeAction); +void TR_treeDestroy(TR_Tree, TR_TreeAction); #endif // __TR_TREE_H__ diff --git a/src/hash/each.c b/src/hash/each.c index 2a6d605..33f68b7 100644 --- a/src/hash/each.c +++ b/src/hash/each.c @@ -34,7 +34,7 @@ walk(const void * node, const void * data, const int depth) cb(node, data); } -void +unsigned long TR_hashEach( TR_Hash this, const void * data, @@ -42,7 +42,7 @@ TR_hashEach( { cb = callback; - TR_treeWalk(this->tree, data, walk); + return TR_treeWalk(this->tree, data, walk); } // vim: set ts=4 sw=4: diff --git a/src/queue/destroy.c b/src/queue/destroy.c index e320afa..8dda38b 100644 --- a/src/queue/destroy.c +++ b/src/queue/destroy.c @@ -29,10 +29,12 @@ void TR_queueDestroy(TR_Queue this) { - TR_Queue node = this->first; + TR_Queue node; pthread_mutex_lock(&(this->lock)); + node = this->first; + while (NULL != node) { TR_Queue next = node->next; if (this->free_msgs) { diff --git a/src/queue/find.c b/src/queue/find.c index 67f51d3..790733e 100644 --- a/src/queue/find.c +++ b/src/queue/find.c @@ -20,6 +20,8 @@ * along with this program. If not, see . */ +#include + #include "trbase.h" #include "tr/queue.h" @@ -28,7 +30,9 @@ TR_queueFind(TR_Queue this, void * msg) { TR_Queue node; + pthread_mutex_lock(&(this->lock)); for (node = this->first; node && node->msg != msg; node = node->next); + pthread_mutex_unlock(&(this->lock)); return node; } diff --git a/src/queue/find_parent.c b/src/queue/find_parent.c index 707c29b..58e971a 100644 --- a/src/queue/find_parent.c +++ b/src/queue/find_parent.c @@ -20,6 +20,8 @@ * along with this program. If not, see . */ +#include + #include "trbase.h" #include "tr/queue.h" @@ -28,7 +30,9 @@ TR_queueFindParent(TR_Queue this, void * msg) { TR_Queue node; + pthread_mutex_lock(&(this->lock)); for (node = this; node->next && node->next->msg != msg; node = node->next); + pthread_mutex_unlock(&(this->lock)); return node->next ? node : NULL; } diff --git a/src/queue/put.c b/src/queue/put.c index 833e386..1e12e74 100644 --- a/src/queue/put.c +++ b/src/queue/put.c @@ -28,10 +28,12 @@ void TR_queuePut(TR_Queue this, void * msg) { - TR_Queue node = (this->last)? this->last : this; + TR_Queue node; pthread_mutex_lock(&(this->lock)); + node = (this->last)? this->last : this; + node->next = TR_new(TR_Queue); this->last = node->next; diff --git a/src/queue/put_first.c b/src/queue/put_first.c index f474e71..dda90bd 100644 --- a/src/queue/put_first.c +++ b/src/queue/put_first.c @@ -28,10 +28,12 @@ void TR_queuePutFirst(TR_Queue this, void * msg) { - TR_Queue current_first = this->first; + TR_Queue current_first; pthread_mutex_lock(&(this->lock)); + current_first = this->first; + this->first = this->next = TR_new(TR_Queue); this->first->next = current_first; this->first->msg = msg; diff --git a/src/tree/delete.c b/src/tree/delete.c index 6b548d4..44b524d 100644 --- a/src/tree/delete.c +++ b/src/tree/delete.c @@ -28,7 +28,7 @@ void * TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp) { - TR_TreeNode node = this->root; + TR_TreeNode node; TR_TreeNode del_node; TR_TreeNode sibling; int found; @@ -36,6 +36,8 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp) pthread_mutex_lock(&(this->lock)); + node = this->root; + TR_TREE_FIND(node, search, found, comp); /* diff --git a/src/tree/destroy.c b/src/tree/destroy.c index be623e1..3272be2 100644 --- a/src/tree/destroy.c +++ b/src/tree/destroy.c @@ -26,10 +26,15 @@ void TR_treeDestroy(TR_Tree this, TR_TreeAction action) { - TR_TreeNode previous = this->root; - TR_TreeNode node = this->root; - int depth = 1; + TR_TreeNode previous; + TR_TreeNode node; + int depth = 1; + pthread_mutex_lock(&(this->lock)); + + previous = this->root; + node = this->root; + /* * I think this has something like O(n+log(n)) on a ballanced * tree because I have to traverse back the rightmost leaf to @@ -83,6 +88,8 @@ TR_treeDestroy(TR_Tree this, TR_TreeAction action) } this->root = NULL; + + pthread_mutex_unlock(&(this->lock)); } // vim: set ts=4 sw=4: diff --git a/src/tree/find.c b/src/tree/find.c index 2518822..f7be76d 100644 --- a/src/tree/find.c +++ b/src/tree/find.c @@ -25,16 +25,19 @@ void * TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp) { - int found; - TR_TreeNode node = this->root; + int found; + TR_TreeNode node; + void * retval; pthread_mutex_lock(&(this->lock)); + node = this->root; TR_TREE_FIND(node, search, found, comp); + retval = found == 0 ? node->data : NULL; pthread_mutex_unlock(&(this->lock)); - return found == 0 ? node->data : NULL; + return retval; } // vim: set ts=4 sw=4: diff --git a/src/tree/insert.c b/src/tree/insert.c index 449f416..f8955a3 100644 --- a/src/tree/insert.c +++ b/src/tree/insert.c @@ -28,12 +28,15 @@ void * TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp) { - TR_TreeNode node = this->root; - TR_TreeNode new_node = NULL; - int found; + TR_TreeNode new_node = NULL; + TR_TreeNode node; + int found; + void * retval; pthread_mutex_lock(&(this->lock)); + node = this->root; + /* * insert the node or return the one in tree if comparison * succeeds. @@ -77,10 +80,11 @@ TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp) * new node at this point...now rabalance the tree */ TR_TREE_BALANCE_INSERT(&(this->root), node); + retval = new_node->data; pthread_mutex_unlock(&(this->lock)); - return new_node->data; + return retval; } // vim: set ts=4 sw=4: diff --git a/src/tree/walk.c b/src/tree/walk.c index d9608ea..f650fd8 100644 --- a/src/tree/walk.c +++ b/src/tree/walk.c @@ -20,14 +20,22 @@ * along with this program. If not, see . */ +#include + #include "tr/tree.h" -void +unsigned long TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) { - TR_TreeNode previous = this->root; - TR_TreeNode node = this->root; - int depth = 1; + TR_TreeNode previous; + TR_TreeNode node; + int depth = 1; + unsigned long processed = 0; + + pthread_mutex_lock(&(this->lock)); + + previous = this->root; + node = this->root; while (NULL != node) { if (previous == TR_TREE_RIGHT(node)) { @@ -40,6 +48,7 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) if (NULL == TR_TREE_LEFT(node) || previous == TR_TREE_LEFT(node)) { if (action) { action(node->data, data, depth); + processed++; } previous = node; @@ -56,6 +65,10 @@ TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) depth++; } } + + pthread_mutex_unlock(&(this->lock)); + + return processed; } // vim: set ts=4 sw=4: