summaryrefslogtreecommitdiff
path: root/ccan/talloc/test/run-external-alloc.c
blob: 0dc9346075a84a49a53a39ca47d76de6873e7a73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <ccan/talloc/talloc.c>
#include <ccan/tap/tap.h>
#include <assert.h>

/* Much testing already done in run.c */

static int ext_alloc_count, ext_free_count, ext_realloc_count, lock_count, unlock_count;
static void *expected_parent;

static void *ext_realloc(const void *parent, void *ptr, size_t size)
{
	ok1(parent == expected_parent);
	if (ptr == NULL)
		ext_alloc_count++;
	if (size == 0)
		ext_free_count++;
	if (ptr && size)
		ext_realloc_count++;
	return realloc(ptr, size);
}

static void ext_lock(const void *ctx)
{
	lock_count++;
}

static void ext_unlock(void)
{
	unlock_count++;
}

int main(void)
{
	char *p, *p2, *head;
	plan_tests(15);

	expected_parent = NULL;
	head = talloc_add_external(NULL, ext_realloc, ext_lock, ext_unlock);
	assert(head);
	ok1(ext_alloc_count == 1);

	expected_parent = head;
	p = talloc_array(head, char, 1);
	ok1(ext_alloc_count == 2);
	assert(p);

	/* Child is also externally allocated */
	expected_parent = p;
	p2 = talloc(p, char);
	ok1(ext_alloc_count == 3);

	expected_parent = head;
	p = talloc_realloc(NULL, p, char, 1000);
	ok1(ext_realloc_count == 1);
	assert(p);

	expected_parent = p;
	talloc_free(p2);
	ok1(ext_free_count == 1);

	expected_parent = head;
	talloc_free(p);
	ok1(ext_free_count == 2);

	expected_parent = NULL;
	talloc_free(head);
	ok1(ext_free_count == 3);

	ok1(lock_count == unlock_count);

	return exit_status();
}