Commit 88d64d65ab05acf95912f022a693f788e81b9be2

Authored by Georg Hopp
1 parent 7a1cb698

try to make data structures thread save by using a mutex

@@ -28,16 +28,16 @@ @@ -28,16 +28,16 @@
28 #include "trbase.h" 28 #include "trbase.h"
29 #include "tr/tree.h" 29 #include "tr/tree.h"
30 30
31 -#define TR_HASH_IS_EMPTY(h) ((h)->root) 31 +#define TR_HASH_IS_EMPTY(h) ((h)->tree->root)
32 32
33 TR_CLASS(TR_Hash) { 33 TR_CLASS(TR_Hash) {
34 - TR_Tree root; 34 + TR_Tree tree;
35 int cleanup_no_free; 35 int cleanup_no_free;
36 }; 36 };
37 TR_INSTANCE_INIT(TR_Hash); 37 TR_INSTANCE_INIT(TR_Hash);
38 TR_CLASSVARS_DECL(TR_Hash) {}; 38 TR_CLASSVARS_DECL(TR_Hash) {};
39 39
40 -#define TR_hashEmpty(hash) (NULL == (hash)->root) 40 +#define TR_hashEmpty(hash) (NULL == (hash)->tree->root)
41 41
42 void * TR_hashAdd(TR_Hash, void *); 42 void * TR_hashAdd(TR_Hash, void *);
43 void * TR_hashDelete(TR_Hash, const char *, size_t); 43 void * TR_hashDelete(TR_Hash, const char *, size_t);
@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
26 #ifndef __TR_QUEUE_H__ 26 #ifndef __TR_QUEUE_H__
27 #define __TR_QUEUE_H__ 27 #define __TR_QUEUE_H__
28 28
  29 +#include <pthread.h>
29 #include <sys/types.h> 30 #include <sys/types.h>
30 31
31 #include "trbase.h" 32 #include "trbase.h"
@@ -35,6 +36,8 @@ TR_CLASS(TR_Queue) { @@ -35,6 +36,8 @@ TR_CLASS(TR_Queue) {
35 void * msg; 36 void * msg;
36 TR_Queue next; 37 TR_Queue next;
37 38
  39 + pthread_mutex_t lock;
  40 +
38 /** 41 /**
39 * first and last are only available in the initial queue 42 * first and last are only available in the initial queue
40 * element (the root). This elelment does not contain any message 43 * element (the root). This elelment does not contain any message
@@ -23,17 +23,26 @@ @@ -23,17 +23,26 @@
23 #ifndef __TR_TREE_H__ 23 #ifndef __TR_TREE_H__
24 #define __TR_TREE_H__ 24 #define __TR_TREE_H__
25 25
  26 +#include <pthread.h>
  27 +
26 #include "tr/tree_macros.h" 28 #include "tr/tree_macros.h"
27 #include "trbase.h" 29 #include "trbase.h"
28 30
29 -TR_CLASS(TR_Tree) { 31 +TR_CLASS(TR_TreeNode) {
30 void * data; 32 void * data;
31 33
32 TR_rbColor color; 34 TR_rbColor color;
33 35
34 - TR_Tree parent;  
35 - TR_Tree left;  
36 - TR_Tree right; 36 + TR_TreeNode parent;
  37 + TR_TreeNode left;
  38 + TR_TreeNode right;
  39 +};
  40 +TR_INSTANCE_INIT(TR_TreeNode);
  41 +TR_CLASSVARS_DECL(TR_TreeNode) {};
  42 +
  43 +TR_CLASS(TR_Tree) {
  44 + TR_TreeNode root;
  45 + pthread_mutex_t lock;
37 }; 46 };
38 TR_INSTANCE_INIT(TR_Tree); 47 TR_INSTANCE_INIT(TR_Tree);
39 TR_CLASSVARS_DECL(TR_Tree) {}; 48 TR_CLASSVARS_DECL(TR_Tree) {};
@@ -42,10 +51,10 @@ typedef int (*TR_TreeComp)(const void *, const void *); @@ -42,10 +51,10 @@ typedef int (*TR_TreeComp)(const void *, const void *);
42 typedef void (*TR_TreeAction)(const void *, const void *, const int); 51 typedef void (*TR_TreeAction)(const void *, const void *, const int);
43 52
44 void * TR_treeFind(TR_Tree, const void *, TR_TreeComp); 53 void * TR_treeFind(TR_Tree, const void *, TR_TreeComp);
45 -void * TR_treeInsert(TR_Tree *, const void *, TR_TreeComp);  
46 -void * TR_treeDelete(TR_Tree *, const void *, TR_TreeComp); 54 +void * TR_treeInsert(TR_Tree, const void *, TR_TreeComp);
  55 +void * TR_treeDelete(TR_Tree, const void *, TR_TreeComp);
47 void TR_treeWalk(TR_Tree, const void *, TR_TreeAction); 56 void TR_treeWalk(TR_Tree, const void *, TR_TreeAction);
48 -void TR_treeDestroy(TR_Tree *, TR_TreeAction); 57 +void TR_treeDestroy(TR_Tree, TR_TreeAction);
49 58
50 #endif // __TR_TREE_H__ 59 #endif // __TR_TREE_H__
51 60
@@ -11,7 +11,7 @@ TRDATALIBS = cbuf/libcbuf.la \ @@ -11,7 +11,7 @@ TRDATALIBS = cbuf/libcbuf.la \
11 lib_LTLIBRARIES = libtrdata.la 11 lib_LTLIBRARIES = libtrdata.la
12 12
13 libtrdata_la_SOURCES = 13 libtrdata_la_SOURCES =
14 -libtrdata_la_CFLAGS = $(AM_CFLAGS) 14 +libtrdata_la_CFLAGS = $(AM_CFLAGS) -lpthread
15 libtrdata_la_LIBADD = $(TRDATALIBS) 15 libtrdata_la_LIBADD = $(TRDATALIBS)
16 16
17 SUBDIRS = cbuf hash queue tree 17 SUBDIRS = cbuf hash queue tree
@@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b) @@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b)
48 void * 48 void *
49 TR_hashAdd(TR_Hash this, void * operand) 49 TR_hashAdd(TR_Hash this, void * operand)
50 { 50 {
51 - void * found = TR_treeInsert(&this->root, operand, hashAddComp); 51 + void * found = TR_treeInsert(this->tree, operand, hashAddComp);
52 52
53 if (NULL == found) { 53 if (NULL == found) {
54 return NULL; 54 return NULL;
@@ -36,10 +36,12 @@ void @@ -36,10 +36,12 @@ void
36 TR_hashCleanup(TR_Hash this) 36 TR_hashCleanup(TR_Hash this)
37 { 37 {
38 if (this->cleanup_no_free) { 38 if (this->cleanup_no_free) {
39 - TR_treeDestroy(&(this->root), NULL); 39 + TR_treeDestroy(this->tree, NULL);
40 } else { 40 } else {
41 - TR_treeDestroy(&(this->root), tDelete); 41 + TR_treeDestroy(this->tree, tDelete);
42 } 42 }
  43 +
  44 + TR_delete(this->tree);
43 } 45 }
44 46
45 // vim: set ts=4 sw=4: 47 // vim: set ts=4 sw=4:
@@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch) @@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
51 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch); 51 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
52 void * found = NULL; 52 void * found = NULL;
53 53
54 - found = TR_treeDelete(&(this->root), &hash, hashDeleteComp); 54 + found = TR_treeDelete(this->tree, &hash, hashDeleteComp);
55 55
56 return found; 56 return found;
57 } 57 }
@@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch) @@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
59 void * 59 void *
60 TR_hashDeleteByVal(TR_Hash this, unsigned long hash) 60 TR_hashDeleteByVal(TR_Hash this, unsigned long hash)
61 { 61 {
62 - void * found = TR_treeDelete(&(this->root), &hash, hashDeleteComp); 62 + void * found = TR_treeDelete(this->tree, &hash, hashDeleteComp);
63 63
64 return found; 64 return found;
65 } 65 }
@@ -42,7 +42,7 @@ TR_hashEach( @@ -42,7 +42,7 @@ TR_hashEach(
42 { 42 {
43 cb = callback; 43 cb = callback;
44 44
45 - TR_treeWalk(this->root, data, walk); 45 + TR_treeWalk(this->tree, data, walk);
46 } 46 }
47 47
48 // vim: set ts=4 sw=4: 48 // vim: set ts=4 sw=4:
@@ -52,7 +52,7 @@ void * @@ -52,7 +52,7 @@ void *
52 TR_hashGet(TR_Hash this, const char * search, size_t nsearch) 52 TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
53 { 53 {
54 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch); 54 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
55 - void * found = TR_treeFind(this->root, &hash, hashGetComp); 55 + void * found = TR_treeFind(this->tree, &hash, hashGetComp);
56 56
57 return found; 57 return found;
58 } 58 }
@@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch) @@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
60 void * 60 void *
61 TR_hashGetByVal(TR_Hash this, unsigned long hash) 61 TR_hashGetByVal(TR_Hash this, unsigned long hash)
62 { 62 {
63 - void * found = TR_treeFind(this->root, &hash, hashGetComp); 63 + void * found = TR_treeFind(this->tree, &hash, hashGetComp);
64 64
65 return found; 65 return found;
66 } 66 }
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 void * 27 void *
28 TR_hashGetFirst(TR_Hash this) 28 TR_hashGetFirst(TR_Hash this)
29 { 29 {
30 - return this->root; 30 + return this->tree->root;
31 } 31 }
32 32
33 // vim: set ts=4 sw=4: 33 // vim: set ts=4 sw=4:
@@ -31,6 +31,10 @@ static @@ -31,6 +31,10 @@ static
31 int 31 int
32 hashCtor(void * _this, va_list * params) 32 hashCtor(void * _this, va_list * params)
33 { 33 {
  34 + TR_Hash this = _this;
  35 +
  36 + this->tree = TR_new(TR_Tree);
  37 +
34 return 0; 38 return 0;
35 } 39 }
36 40
@@ -41,6 +45,8 @@ hashDtor(void * _this) @@ -41,6 +45,8 @@ hashDtor(void * _this)
41 TR_Hash this = _this; 45 TR_Hash this = _this;
42 46
43 TR_hashCleanup(this); 47 TR_hashCleanup(this);
  48 +
  49 + TR_delete(this->tree);
44 } 50 }
45 51
46 TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL); 52 TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL);
@@ -26,9 +26,16 @@ @@ -26,9 +26,16 @@
26 void 26 void
27 TR_queueDelete(TR_Queue this, void * msg) 27 TR_queueDelete(TR_Queue this, void * msg)
28 { 28 {
29 - TR_Queue node, parent = TR_queueFindParent(this, msg); 29 + TR_Queue node, parent;
  30 +
  31 + pthread_mutex_lock(&(this->lock));
30 32
31 - if (! parent) return; 33 + parent = TR_queueFindParent(this, msg);
  34 +
  35 + if (! parent) {
  36 + pthread_mutex_unlock(&(this->lock));
  37 + return;
  38 + }
32 39
33 node = parent->next; 40 node = parent->next;
34 parent->next = node->next; 41 parent->next = node->next;
@@ -40,6 +47,8 @@ TR_queueDelete(TR_Queue this, void * msg) @@ -40,6 +47,8 @@ TR_queueDelete(TR_Queue this, void * msg)
40 } 47 }
41 TR_delete(node); 48 TR_delete(node);
42 this->nmsg--; 49 this->nmsg--;
  50 +
  51 + pthread_mutex_unlock(&(this->lock));
43 } 52 }
44 53
45 // vim: set ts=4 sw=4: 54 // vim: set ts=4 sw=4:
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 */ 21 */
22 22
23 #include <stdarg.h> 23 #include <stdarg.h>
  24 +#include <pthread.h>
24 25
25 #include "trbase.h" 26 #include "trbase.h"
26 #include "tr/queue.h" 27 #include "tr/queue.h"
@@ -30,6 +31,8 @@ TR_queueDestroy(TR_Queue this) @@ -30,6 +31,8 @@ TR_queueDestroy(TR_Queue this)
30 { 31 {
31 TR_Queue node = this->first; 32 TR_Queue node = this->first;
32 33
  34 + pthread_mutex_lock(&(this->lock));
  35 +
33 while (NULL != node) { 36 while (NULL != node) {
34 TR_Queue next = node->next; 37 TR_Queue next = node->next;
35 if (this->free_msgs) { 38 if (this->free_msgs) {
@@ -41,6 +44,8 @@ TR_queueDestroy(TR_Queue this) @@ -41,6 +44,8 @@ TR_queueDestroy(TR_Queue this)
41 44
42 this->first = this->next = this->last = NULL; 45 this->first = this->next = this->last = NULL;
43 this->nmsg = 0; 46 this->nmsg = 0;
  47 +
  48 + pthread_mutex_unlock(&(this->lock));
44 } 49 }
45 50
46 // vim: set ts=4 sw=4: 51 // vim: set ts=4 sw=4:
@@ -20,6 +20,8 @@ @@ -20,6 +20,8 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 #include "trbase.h" 25 #include "trbase.h"
24 #include "tr/queue.h" 26 #include "tr/queue.h"
25 27
@@ -29,7 +31,10 @@ TR_queueGet(TR_Queue this) @@ -29,7 +31,10 @@ TR_queueGet(TR_Queue this)
29 TR_Queue first; 31 TR_Queue first;
30 void * msg; 32 void * msg;
31 33
  34 + pthread_mutex_lock(&(this->lock));
  35 +
32 if (NULL == this->first) { 36 if (NULL == this->first) {
  37 + pthread_mutex_unlock(&(this->lock));
33 return NULL; 38 return NULL;
34 } 39 }
35 40
@@ -45,6 +50,8 @@ TR_queueGet(TR_Queue this) @@ -45,6 +50,8 @@ TR_queueGet(TR_Queue this)
45 this->first = first; 50 this->first = first;
46 this->nmsg--; 51 this->nmsg--;
47 52
  53 + pthread_mutex_unlock(&(this->lock));
  54 +
48 return msg; 55 return msg;
49 } 56 }
50 57
@@ -20,6 +20,8 @@ @@ -20,6 +20,8 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 #include "trbase.h" 25 #include "trbase.h"
24 #include "tr/queue.h" 26 #include "tr/queue.h"
25 27
@@ -28,6 +30,8 @@ TR_queuePut(TR_Queue this, void * msg) @@ -28,6 +30,8 @@ TR_queuePut(TR_Queue this, void * msg)
28 { 30 {
29 TR_Queue node = (this->last)? this->last : this; 31 TR_Queue node = (this->last)? this->last : this;
30 32
  33 + pthread_mutex_lock(&(this->lock));
  34 +
31 node->next = TR_new(TR_Queue); 35 node->next = TR_new(TR_Queue);
32 this->last = node->next; 36 this->last = node->next;
33 37
@@ -37,6 +41,8 @@ TR_queuePut(TR_Queue this, void * msg) @@ -37,6 +41,8 @@ TR_queuePut(TR_Queue this, void * msg)
37 41
38 node->next->msg = msg; 42 node->next->msg = msg;
39 this->nmsg++; 43 this->nmsg++;
  44 +
  45 + pthread_mutex_unlock(&(this->lock));
40 } 46 }
41 47
42 // vim: set ts=4 sw=4: 48 // vim: set ts=4 sw=4:
@@ -20,6 +20,8 @@ @@ -20,6 +20,8 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 #include "trbase.h" 25 #include "trbase.h"
24 #include "tr/queue.h" 26 #include "tr/queue.h"
25 27
@@ -28,11 +30,15 @@ TR_queuePutFirst(TR_Queue this, void * msg) @@ -28,11 +30,15 @@ TR_queuePutFirst(TR_Queue this, void * msg)
28 { 30 {
29 TR_Queue current_first = this->first; 31 TR_Queue current_first = this->first;
30 32
  33 + pthread_mutex_lock(&(this->lock));
  34 +
31 this->first = this->next = TR_new(TR_Queue); 35 this->first = this->next = TR_new(TR_Queue);
32 this->first->next = current_first; 36 this->first->next = current_first;
33 this->first->msg = msg; 37 this->first->msg = msg;
34 this->last = this->last ? this->last : this->first; 38 this->last = this->last ? this->last : this->first;
35 this->nmsg++; 39 this->nmsg++;
  40 +
  41 + pthread_mutex_unlock(&(this->lock));
36 } 42 }
37 43
38 // vim: set ts=4 sw=4: 44 // vim: set ts=4 sw=4:
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 */ 21 */
22 22
23 #include <stdarg.h> 23 #include <stdarg.h>
  24 +#include <pthread.h>
24 25
25 #include "trbase.h" 26 #include "trbase.h"
26 #include "tr/queue.h" 27 #include "tr/queue.h"
@@ -32,6 +33,7 @@ queueCtor(void * _this, va_list * params) @@ -32,6 +33,7 @@ queueCtor(void * _this, va_list * params)
32 TR_Queue this = _this; 33 TR_Queue this = _this;
33 34
34 this->free_msgs = 1; 35 this->free_msgs = 1;
  36 + pthread_mutex_init(&(this->lock), NULL);
35 37
36 return 0; 38 return 0;
37 } 39 }
@@ -40,7 +42,10 @@ static @@ -40,7 +42,10 @@ static
40 void 42 void
41 queueDtor(void * _this) 43 queueDtor(void * _this)
42 { 44 {
43 - TR_queueDestroy((TR_Queue)_this); 45 + TR_Queue this = _this;
  46 +
  47 + TR_queueDestroy(this);
  48 + pthread_mutex_destroy(&(this->lock));
44 } 49 }
45 50
46 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL); 51 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);
@@ -2,6 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 @@ -2,6 +2,7 @@ ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4 TREE = tree.c \ 4 TREE = tree.c \
  5 + tree_node.c \
5 find.c \ 6 find.c \
6 insert.c \ 7 insert.c \
7 delete.c \ 8 delete.c \
@@ -20,18 +20,21 @@ @@ -20,18 +20,21 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 #include "trbase.h" 25 #include "trbase.h"
24 #include "tr/tree.h" 26 #include "tr/tree.h"
25 27
26 void * 28 void *
27 -TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) 29 +TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
28 { 30 {
29 - TR_Tree node = *this;  
30 - TR_Tree del_node;  
31 - TR_Tree sibling;  
32 - int found; 31 + TR_TreeNode node = this->root;
  32 + TR_TreeNode del_node;
  33 + TR_TreeNode sibling;
  34 + int found;
  35 + void * data;
33 36
34 - void * data; 37 + pthread_mutex_lock(&(this->lock));
35 38
36 TR_TREE_FIND(node, search, found, comp); 39 TR_TREE_FIND(node, search, found, comp);
37 40
@@ -39,6 +42,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -39,6 +42,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
39 * nothing was found...return NULL to indicate this. 42 * nothing was found...return NULL to indicate this.
40 */ 43 */
41 if (found != 0) { 44 if (found != 0) {
  45 + pthread_mutex_unlock(&(this->lock));
42 return NULL; 46 return NULL;
43 } 47 }
44 48
@@ -57,7 +61,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -57,7 +61,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
57 * out inOrderSuccessor and remove the inOrderSuccessor. 61 * out inOrderSuccessor and remove the inOrderSuccessor.
58 */ 62 */
59 if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) { 63 if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) {
60 - TR_Tree successor; 64 + TR_TreeNode successor;
61 65
62 TR_TREE_INORDER_SUCC(node, successor); 66 TR_TREE_INORDER_SUCC(node, successor);
63 67
@@ -66,12 +70,12 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -66,12 +70,12 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
66 } 70 }
67 71
68 { 72 {
69 - TR_Tree child = TR_TREE_CHILD(node); 73 + TR_TreeNode child = TR_TREE_CHILD(node);
70 74
71 /* 75 /*
72 * if we still have one child replace ourself with it. 76 * if we still have one child replace ourself with it.
73 */ 77 */
74 - TR_TREE_REPLACE_NODE(this, node, child); 78 + TR_TREE_REPLACE_NODE(&(this->root), node, child);
75 79
76 /* 80 /*
77 * and finally delete the node...and prepare ourselfs 81 * and finally delete the node...and prepare ourselfs
@@ -81,6 +85,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -81,6 +85,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
81 if (NULL != child && rbRed == child->color) { 85 if (NULL != child && rbRed == child->color) {
82 child->color = rbBlack; 86 child->color = rbBlack;
83 TR_delete(node); 87 TR_delete(node);
  88 + pthread_mutex_unlock(&(this->lock));
84 return data; 89 return data;
85 } else { 90 } else {
86 del_node = node; 91 del_node = node;
@@ -94,6 +99,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -94,6 +99,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
94 } 99 }
95 } else { 100 } else {
96 TR_delete(node); 101 TR_delete(node);
  102 + pthread_mutex_unlock(&(this->lock));
97 return data; 103 return data;
98 } 104 }
99 } 105 }
@@ -105,9 +111,12 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -105,9 +111,12 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
105 * rebalancing process...(this does not make much sense, but 111 * rebalancing process...(this does not make much sense, but
106 * to be honest I don't know now.) 112 * to be honest I don't know now.)
107 */ 113 */
108 - TR_TREE_BALANCE_DELETE(this, node, sibling); 114 + TR_TREE_BALANCE_DELETE(&(this->root), node, sibling);
109 115
110 TR_delete(del_node); 116 TR_delete(del_node);
  117 +
  118 + pthread_mutex_unlock(&(this->lock));
  119 +
111 return data; 120 return data;
112 } 121 }
113 122
@@ -24,11 +24,11 @@ @@ -24,11 +24,11 @@
24 #include "tr/tree.h" 24 #include "tr/tree.h"
25 25
26 void 26 void
27 -TR_treeDestroy(TR_Tree * this, TR_TreeAction action) 27 +TR_treeDestroy(TR_Tree this, TR_TreeAction action)
28 { 28 {
29 - TR_Tree previous = * this;  
30 - TR_Tree node = * this;  
31 - int depth = 1; 29 + TR_TreeNode previous = this->root;
  30 + TR_TreeNode node = this->root;
  31 + int depth = 1;
32 32
33 /* 33 /*
34 * I think this has something like O(n+log(n)) on a ballanced 34 * I think this has something like O(n+log(n)) on a ballanced
@@ -44,7 +44,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action) @@ -44,7 +44,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
44 || previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node)) 44 || previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node))
45 || previous == TR_TREE_RIGHT(node)) { 45 || previous == TR_TREE_RIGHT(node)) {
46 46
47 - TR_Tree parent = TR_TREE_PARENT(node); 47 + TR_TreeNode parent = TR_TREE_PARENT(node);
48 48
49 if (action) { 49 if (action) {
50 action(node->data, NULL, depth); 50 action(node->data, NULL, depth);
@@ -82,7 +82,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action) @@ -82,7 +82,7 @@ TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
82 } 82 }
83 } 83 }
84 84
85 - *this = NULL; 85 + this->root = NULL;
86 } 86 }
87 87
88 // vim: set ts=4 sw=4: 88 // vim: set ts=4 sw=4:
@@ -25,11 +25,16 @@ @@ -25,11 +25,16 @@
25 void * 25 void *
26 TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp) 26 TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp)
27 { 27 {
28 - int found; 28 + int found;
  29 + TR_TreeNode node = this->root;
29 30
30 - TR_TREE_FIND(this, search, found, comp); 31 + pthread_mutex_lock(&(this->lock));
31 32
32 - return found == 0 ? this->data : NULL; 33 + TR_TREE_FIND(node, search, found, comp);
  34 +
  35 + pthread_mutex_unlock(&(this->lock));
  36 +
  37 + return found == 0 ? node->data : NULL;
33 } 38 }
34 39
35 // vim: set ts=4 sw=4: 40 // vim: set ts=4 sw=4:
@@ -20,16 +20,20 @@ @@ -20,16 +20,20 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 #include "trbase.h" 25 #include "trbase.h"
24 #include "tr/tree.h" 26 #include "tr/tree.h"
25 27
26 void * 28 void *
27 -TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp) 29 +TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp)
28 { 30 {
29 - TR_Tree node = *this;  
30 - TR_Tree new_node = NULL; 31 + TR_TreeNode node = this->root;
  32 + TR_TreeNode new_node = NULL;
31 int found; 33 int found;
32 34
  35 + pthread_mutex_lock(&(this->lock));
  36 +
33 /* 37 /*
34 * insert the node or return the one in tree if comparison 38 * insert the node or return the one in tree if comparison
35 * succeeds. 39 * succeeds.
@@ -39,11 +43,13 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -39,11 +43,13 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
39 * if the root is NULL we simple add the element and set 43 * if the root is NULL we simple add the element and set
40 * node to it. 44 * node to it.
41 */ 45 */
42 - *this = node = new_node = TR_new(TR_Tree, search); 46 + this->root = node = new_node = TR_new(TR_TreeNode, search);
43 } else { 47 } else {
44 TR_TREE_FIND(node, search, found, comp); 48 TR_TREE_FIND(node, search, found, comp);
45 49
46 if (found == 0) { 50 if (found == 0) {
  51 + pthread_mutex_unlock(&(this->lock));
  52 +
47 // This differs from tsearch, which is the posix equivalent to 53 // This differs from tsearch, which is the posix equivalent to
48 // this function in that it will not replace an existing value. 54 // this function in that it will not replace an existing value.
49 // If there is a value for the given key in the tree it will be 55 // If there is a value for the given key in the tree it will be
@@ -55,11 +61,11 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -55,11 +61,11 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
55 } else { 61 } else {
56 // not found 62 // not found
57 if (0 < found) { 63 if (0 < found) {
58 - node->left = TR_new(TR_Tree, search); 64 + node->left = TR_new(TR_TreeNode, search);
59 node->left->parent = node; 65 node->left->parent = node;
60 node = new_node = node->left; 66 node = new_node = node->left;
61 } else { 67 } else {
62 - node->right = TR_new(TR_Tree, search); 68 + node->right = TR_new(TR_TreeNode, search);
63 node->right->parent = node; 69 node->right->parent = node;
64 node = new_node = node->right; 70 node = new_node = node->right;
65 } 71 }
@@ -70,7 +76,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -70,7 +76,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
70 * we expect node not to be NULL and pointing to our 76 * we expect node not to be NULL and pointing to our
71 * new node at this point...now rabalance the tree 77 * new node at this point...now rabalance the tree
72 */ 78 */
73 - TR_TREE_BALANCE_INSERT(this, node); 79 + TR_TREE_BALANCE_INSERT(&(this->root), node);
  80 +
  81 + pthread_mutex_unlock(&(this->lock));
74 82
75 return new_node->data; 83 return new_node->data;
76 } 84 }
@@ -33,11 +33,8 @@ treeCtor(void * _this, va_list * params) @@ -33,11 +33,8 @@ treeCtor(void * _this, va_list * params)
33 { 33 {
34 TR_Tree this = _this; 34 TR_Tree this = _this;
35 35
36 - this->data = va_arg(*params, void *);  
37 - this->color = rbRed;  
38 - this->parent = NULL;  
39 - this->left = NULL;  
40 - this->right = NULL; 36 + this->root = NULL;
  37 + pthread_mutex_init(&(this->lock), NULL);
41 38
42 return 0; 39 return 0;
43 } 40 }
@@ -46,6 +43,8 @@ static @@ -46,6 +43,8 @@ static
46 void 43 void
47 treeDtor(void * _this) 44 treeDtor(void * _this)
48 { 45 {
  46 + TR_Tree this = _this;
  47 + pthread_mutex_destroy(&(this->lock));
49 } 48 }
50 49
51 TR_INIT_IFACE(TR_Class, treeCtor, treeDtor, NULL); 50 TR_INIT_IFACE(TR_Class, treeCtor, treeDtor, NULL);
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2014 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#define _GNU_SOURCE
  24 +
  25 +#include <stdarg.h>
  26 +
  27 +#include "trbase.h"
  28 +#include "tr/tree.h"
  29 +
  30 +static
  31 +int
  32 +treeNodeCtor(void * _this, va_list * params)
  33 +{
  34 + TR_TreeNode this = _this;
  35 +
  36 + this->data = va_arg(*params, void *);
  37 + this->color = rbRed;
  38 + this->parent = NULL;
  39 + this->left = NULL;
  40 + this->right = NULL;
  41 +
  42 + return 0;
  43 +}
  44 +
  45 +static void treeNodeDtor(void * _this) {}
  46 +
  47 +TR_INIT_IFACE(TR_Class, treeNodeCtor, treeNodeDtor, NULL);
  48 +TR_CREATE_CLASS(TR_TreeNode, NULL, NULL, TR_IF(TR_Class));
  49 +
  50 +// vim: set ts=4 sw=4:
@@ -25,9 +25,9 @@ @@ -25,9 +25,9 @@
25 void 25 void
26 TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action) 26 TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
27 { 27 {
28 - TR_Tree previous = this;  
29 - TR_Tree node = this;  
30 - int depth = 1; 28 + TR_TreeNode previous = this->root;
  29 + TR_TreeNode node = this->root;
  30 + int depth = 1;
31 31
32 while (NULL != node) { 32 while (NULL != node) {
33 if (previous == TR_TREE_RIGHT(node)) { 33 if (previous == TR_TREE_RIGHT(node)) {
Please register or login to post a comment