]> git.ozlabs.org Git - ccan/blob - ccan/tal/test/run-destructor.c
tal: don't defer-after-free if a destructor deletes itself.
[ccan] / ccan / tal / test / run-destructor.c
1 #include <ccan/tal/tal.h>
2 #include <ccan/tal/tal.c>
3 #include <ccan/tap/tap.h>
4
5 static char *parent, *child;
6 static int destroy_count;
7
8 /* Parent gets destroyed first. */
9 static void destroy_parent(char *p)
10 {
11         ok1(p == parent);
12         ok1(destroy_count == 0);
13         /* Can still access child. */
14         *child = '1';
15         destroy_count++;
16 }
17
18 static void destroy_child(char *p)
19 {
20         ok1(p == child);
21         ok1(destroy_count == 1);
22         /* Can still access parent (though destructor has been called). */
23         *parent = '1';
24         destroy_count++;
25 }
26
27 static void destroy_inc(char *p UNNEEDED)
28 {
29         destroy_count++;
30 }
31
32 static void remove_own_destructor(char *p)
33 {
34         destroy_count++;
35         ok1(!tal_del_destructor(p, remove_own_destructor));
36 }
37
38 int main(void)
39 {
40         char *child2;
41
42         plan_tests(21);
43
44         destroy_count = 0;
45         parent = tal(NULL, char);
46         child = tal(parent, char);
47         ok1(tal_add_destructor(parent, destroy_parent));
48         ok1(tal_add_destructor(child, destroy_child));
49         tal_free(parent);
50         ok1(destroy_count == 2);
51
52         destroy_count = 0;
53         parent = tal(NULL, char);
54         child = tal(parent, char);
55         ok1(tal_add_destructor(parent, destroy_parent));
56         ok1(tal_add_destructor(child, destroy_child));
57         ok1(tal_del_destructor(child, destroy_child));
58         tal_free(parent);
59         ok1(destroy_count == 1);
60
61         destroy_count = 0;
62         parent = tal(NULL, char);
63         child = tal(parent, char);
64         child2 = tal(parent, char);
65         ok1(tal_add_destructor(parent, destroy_inc));
66         ok1(tal_add_destructor(parent, destroy_inc));
67         ok1(tal_add_destructor(child, destroy_inc));
68         ok1(tal_add_destructor(child2, destroy_inc));
69         tal_free(parent);
70         ok1(destroy_count == 4);
71
72         destroy_count = 0;
73         parent = tal(NULL, char);
74         ok1(tal_add_destructor(parent, remove_own_destructor));
75         tal_free(parent);
76         ok1(destroy_count == 1);
77         
78         tal_cleanup();
79         return exit_status();
80 }