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 28 #include "trbase.h"
29 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 33 TR_CLASS(TR_Hash) {
34   - TR_Tree root;
  34 + TR_Tree tree;
35 35 int cleanup_no_free;
36 36 };
37 37 TR_INSTANCE_INIT(TR_Hash);
38 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 42 void * TR_hashAdd(TR_Hash, void *);
43 43 void * TR_hashDelete(TR_Hash, const char *, size_t);
... ...
... ... @@ -26,6 +26,7 @@
26 26 #ifndef __TR_QUEUE_H__
27 27 #define __TR_QUEUE_H__
28 28
  29 +#include <pthread.h>
29 30 #include <sys/types.h>
30 31
31 32 #include "trbase.h"
... ... @@ -35,6 +36,8 @@ TR_CLASS(TR_Queue) {
35 36 void * msg;
36 37 TR_Queue next;
37 38
  39 + pthread_mutex_t lock;
  40 +
38 41 /**
39 42 * first and last are only available in the initial queue
40 43 * element (the root). This elelment does not contain any message
... ...
... ... @@ -23,17 +23,26 @@
23 23 #ifndef __TR_TREE_H__
24 24 #define __TR_TREE_H__
25 25
  26 +#include <pthread.h>
  27 +
26 28 #include "tr/tree_macros.h"
27 29 #include "trbase.h"
28 30
29   -TR_CLASS(TR_Tree) {
  31 +TR_CLASS(TR_TreeNode) {
30 32 void * data;
31 33
32 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 47 TR_INSTANCE_INIT(TR_Tree);
39 48 TR_CLASSVARS_DECL(TR_Tree) {};
... ... @@ -42,10 +51,10 @@ typedef int (*TR_TreeComp)(const void *, const void *);
42 51 typedef void (*TR_TreeAction)(const void *, const void *, const int);
43 52
44 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 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 59 #endif // __TR_TREE_H__
51 60
... ...
... ... @@ -11,7 +11,7 @@ TRDATALIBS = cbuf/libcbuf.la \
11 11 lib_LTLIBRARIES = libtrdata.la
12 12
13 13 libtrdata_la_SOURCES =
14   -libtrdata_la_CFLAGS = $(AM_CFLAGS)
  14 +libtrdata_la_CFLAGS = $(AM_CFLAGS) -lpthread
15 15 libtrdata_la_LIBADD = $(TRDATALIBS)
16 16
17 17 SUBDIRS = cbuf hash queue tree
... ...
... ... @@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b)
48 48 void *
49 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 53 if (NULL == found) {
54 54 return NULL;
... ...
... ... @@ -36,10 +36,12 @@ void
36 36 TR_hashCleanup(TR_Hash this)
37 37 {
38 38 if (this->cleanup_no_free) {
39   - TR_treeDestroy(&(this->root), NULL);
  39 + TR_treeDestroy(this->tree, NULL);
40 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 47 // vim: set ts=4 sw=4:
... ...
... ... @@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
51 51 unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
52 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 56 return found;
57 57 }
... ... @@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
59 59 void *
60 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 64 return found;
65 65 }
... ...
... ... @@ -42,7 +42,7 @@ TR_hashEach(
42 42 {
43 43 cb = callback;
44 44
45   - TR_treeWalk(this->root, data, walk);
  45 + TR_treeWalk(this->tree, data, walk);
46 46 }
47 47
48 48 // vim: set ts=4 sw=4:
... ...
... ... @@ -52,7 +52,7 @@ void *
52 52 TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
53 53 {
54 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 57 return found;
58 58 }
... ... @@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
60 60 void *
61 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 65 return found;
66 66 }
... ...
... ... @@ -27,7 +27,7 @@
27 27 void *
28 28 TR_hashGetFirst(TR_Hash this)
29 29 {
30   - return this->root;
  30 + return this->tree->root;
31 31 }
32 32
33 33 // vim: set ts=4 sw=4:
... ...
... ... @@ -31,6 +31,10 @@ static
31 31 int
32 32 hashCtor(void * _this, va_list * params)
33 33 {
  34 + TR_Hash this = _this;
  35 +
  36 + this->tree = TR_new(TR_Tree);
  37 +
34 38 return 0;
35 39 }
36 40
... ... @@ -41,6 +45,8 @@ hashDtor(void * _this)
41 45 TR_Hash this = _this;
42 46
43 47 TR_hashCleanup(this);
  48 +
  49 + TR_delete(this->tree);
44 50 }
45 51
46 52 TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL);
... ...
... ... @@ -26,9 +26,16 @@
26 26 void
27 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 40 node = parent->next;
34 41 parent->next = node->next;
... ... @@ -40,6 +47,8 @@ TR_queueDelete(TR_Queue this, void * msg)
40 47 }
41 48 TR_delete(node);
42 49 this->nmsg--;
  50 +
  51 + pthread_mutex_unlock(&(this->lock));
43 52 }
44 53
45 54 // vim: set ts=4 sw=4:
... ...
... ... @@ -21,6 +21,7 @@
21 21 */
22 22
23 23 #include <stdarg.h>
  24 +#include <pthread.h>
24 25
25 26 #include "trbase.h"
26 27 #include "tr/queue.h"
... ... @@ -30,6 +31,8 @@ TR_queueDestroy(TR_Queue this)
30 31 {
31 32 TR_Queue node = this->first;
32 33
  34 + pthread_mutex_lock(&(this->lock));
  35 +
33 36 while (NULL != node) {
34 37 TR_Queue next = node->next;
35 38 if (this->free_msgs) {
... ... @@ -41,6 +44,8 @@ TR_queueDestroy(TR_Queue this)
41 44
42 45 this->first = this->next = this->last = NULL;
43 46 this->nmsg = 0;
  47 +
  48 + pthread_mutex_unlock(&(this->lock));
44 49 }
45 50
46 51 // vim: set ts=4 sw=4:
... ...
... ... @@ -20,6 +20,8 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 25 #include "trbase.h"
24 26 #include "tr/queue.h"
25 27
... ... @@ -29,7 +31,10 @@ TR_queueGet(TR_Queue this)
29 31 TR_Queue first;
30 32 void * msg;
31 33
  34 + pthread_mutex_lock(&(this->lock));
  35 +
32 36 if (NULL == this->first) {
  37 + pthread_mutex_unlock(&(this->lock));
33 38 return NULL;
34 39 }
35 40
... ... @@ -45,6 +50,8 @@ TR_queueGet(TR_Queue this)
45 50 this->first = first;
46 51 this->nmsg--;
47 52
  53 + pthread_mutex_unlock(&(this->lock));
  54 +
48 55 return msg;
49 56 }
50 57
... ...
... ... @@ -20,6 +20,8 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 25 #include "trbase.h"
24 26 #include "tr/queue.h"
25 27
... ... @@ -28,6 +30,8 @@ TR_queuePut(TR_Queue this, void * msg)
28 30 {
29 31 TR_Queue node = (this->last)? this->last : this;
30 32
  33 + pthread_mutex_lock(&(this->lock));
  34 +
31 35 node->next = TR_new(TR_Queue);
32 36 this->last = node->next;
33 37
... ... @@ -37,6 +41,8 @@ TR_queuePut(TR_Queue this, void * msg)
37 41
38 42 node->next->msg = msg;
39 43 this->nmsg++;
  44 +
  45 + pthread_mutex_unlock(&(this->lock));
40 46 }
41 47
42 48 // vim: set ts=4 sw=4:
... ...
... ... @@ -20,6 +20,8 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 25 #include "trbase.h"
24 26 #include "tr/queue.h"
25 27
... ... @@ -28,11 +30,15 @@ TR_queuePutFirst(TR_Queue this, void * msg)
28 30 {
29 31 TR_Queue current_first = this->first;
30 32
  33 + pthread_mutex_lock(&(this->lock));
  34 +
31 35 this->first = this->next = TR_new(TR_Queue);
32 36 this->first->next = current_first;
33 37 this->first->msg = msg;
34 38 this->last = this->last ? this->last : this->first;
35 39 this->nmsg++;
  40 +
  41 + pthread_mutex_unlock(&(this->lock));
36 42 }
37 43
38 44 // vim: set ts=4 sw=4:
... ...
... ... @@ -21,6 +21,7 @@
21 21 */
22 22
23 23 #include <stdarg.h>
  24 +#include <pthread.h>
24 25
25 26 #include "trbase.h"
26 27 #include "tr/queue.h"
... ... @@ -32,6 +33,7 @@ queueCtor(void * _this, va_list * params)
32 33 TR_Queue this = _this;
33 34
34 35 this->free_msgs = 1;
  36 + pthread_mutex_init(&(this->lock), NULL);
35 37
36 38 return 0;
37 39 }
... ... @@ -40,7 +42,10 @@ static
40 42 void
41 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 51 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);
... ...
... ... @@ -2,6 +2,7 @@ ACLOCAL_AMFLAGS = -I m4
2 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4 4 TREE = tree.c \
  5 + tree_node.c \
5 6 find.c \
6 7 insert.c \
7 8 delete.c \
... ...
... ... @@ -20,18 +20,21 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 25 #include "trbase.h"
24 26 #include "tr/tree.h"
25 27
26 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 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 42 * nothing was found...return NULL to indicate this.
40 43 */
41 44 if (found != 0) {
  45 + pthread_mutex_unlock(&(this->lock));
42 46 return NULL;
43 47 }
44 48
... ... @@ -57,7 +61,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
57 61 * out inOrderSuccessor and remove the inOrderSuccessor.
58 62 */
59 63 if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) {
60   - TR_Tree successor;
  64 + TR_TreeNode successor;
61 65
62 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 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 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 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 85 if (NULL != child && rbRed == child->color) {
82 86 child->color = rbBlack;
83 87 TR_delete(node);
  88 + pthread_mutex_unlock(&(this->lock));
84 89 return data;
85 90 } else {
86 91 del_node = node;
... ... @@ -94,6 +99,7 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
94 99 }
95 100 } else {
96 101 TR_delete(node);
  102 + pthread_mutex_unlock(&(this->lock));
97 103 return data;
98 104 }
99 105 }
... ... @@ -105,9 +111,12 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
105 111 * rebalancing process...(this does not make much sense, but
106 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 116 TR_delete(del_node);
  117 +
  118 + pthread_mutex_unlock(&(this->lock));
  119 +
111 120 return data;
112 121 }
113 122
... ...
... ... @@ -24,11 +24,11 @@
24 24 #include "tr/tree.h"
25 25
26 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 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 44 || previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node))
45 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 49 if (action) {
50 50 action(node->data, NULL, depth);
... ... @@ -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 88 // vim: set ts=4 sw=4:
... ...
... ... @@ -25,11 +25,16 @@
25 25 void *
26 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 40 // vim: set ts=4 sw=4:
... ...
... ... @@ -20,16 +20,20 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include <pthread.h>
  24 +
23 25 #include "trbase.h"
24 26 #include "tr/tree.h"
25 27
26 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 33 int found;
32 34
  35 + pthread_mutex_lock(&(this->lock));
  36 +
33 37 /*
34 38 * insert the node or return the one in tree if comparison
35 39 * succeeds.
... ... @@ -39,11 +43,13 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
39 43 * if the root is NULL we simple add the element and set
40 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 47 } else {
44 48 TR_TREE_FIND(node, search, found, comp);
45 49
46 50 if (found == 0) {
  51 + pthread_mutex_unlock(&(this->lock));
  52 +
47 53 // This differs from tsearch, which is the posix equivalent to
48 54 // this function in that it will not replace an existing value.
49 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 61 } else {
56 62 // not found
57 63 if (0 < found) {
58   - node->left = TR_new(TR_Tree, search);
  64 + node->left = TR_new(TR_TreeNode, search);
59 65 node->left->parent = node;
60 66 node = new_node = node->left;
61 67 } else {
62   - node->right = TR_new(TR_Tree, search);
  68 + node->right = TR_new(TR_TreeNode, search);
63 69 node->right->parent = node;
64 70 node = new_node = node->right;
65 71 }
... ... @@ -70,7 +76,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
70 76 * we expect node not to be NULL and pointing to our
71 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 83 return new_node->data;
76 84 }
... ...
... ... @@ -33,11 +33,8 @@ treeCtor(void * _this, va_list * params)
33 33 {
34 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 39 return 0;
43 40 }
... ... @@ -46,6 +43,8 @@ static
46 43 void
47 44 treeDtor(void * _this)
48 45 {
  46 + TR_Tree this = _this;
  47 + pthread_mutex_destroy(&(this->lock));
49 48 }
50 49
51 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 25 void
26 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 32 while (NULL != node) {
33 33 if (previous == TR_TREE_RIGHT(node)) {
... ...
Please register or login to post a comment