/src/dovecot/src/lib/memarea.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */ |
2 | | |
3 | | #include "lib.h" |
4 | | #include "memarea.h" |
5 | | |
6 | | struct memarea { |
7 | | const void *data; |
8 | | size_t size; |
9 | | |
10 | | memarea_free_callback_t *callback; |
11 | | void *context; |
12 | | |
13 | | int refcount; |
14 | | }; |
15 | | |
16 | | static struct memarea memarea_empty = { |
17 | | .refcount = 1, |
18 | | }; |
19 | | |
20 | | #undef memarea_init |
21 | | struct memarea * |
22 | | memarea_init(const void *data, size_t size, |
23 | | memarea_free_callback_t *callback, void *context) |
24 | 5.13k | { |
25 | 5.13k | struct memarea *area; |
26 | | |
27 | 5.13k | i_assert(callback != NULL); |
28 | | |
29 | 5.13k | area = i_new(struct memarea, 1); |
30 | 5.13k | area->data = data; |
31 | 5.13k | area->size = size; |
32 | 5.13k | area->callback = callback; |
33 | 5.13k | area->context = context; |
34 | 5.13k | area->refcount = 1; |
35 | 5.13k | return area; |
36 | 5.13k | } |
37 | | |
38 | | struct memarea *memarea_init_empty(void) |
39 | 3.10k | { |
40 | 3.10k | i_assert(memarea_empty.refcount > 0); |
41 | 3.10k | memarea_empty.refcount++; |
42 | 3.10k | return &memarea_empty; |
43 | 3.10k | } |
44 | | |
45 | | void memarea_ref(struct memarea *area) |
46 | 107 | { |
47 | 107 | i_assert(area->refcount > 0); |
48 | 107 | area->refcount++; |
49 | 107 | } |
50 | | |
51 | | void memarea_unref(struct memarea **_area) |
52 | 8.34k | { |
53 | 8.34k | struct memarea *area = *_area; |
54 | | |
55 | 8.34k | *_area = NULL; |
56 | 8.34k | i_assert(area->refcount > 0); |
57 | | |
58 | 8.34k | if (--area->refcount > 0) |
59 | 3.20k | return; |
60 | 8.34k | i_assert(area != &memarea_empty); |
61 | 5.13k | area->callback(area->context); |
62 | 5.13k | i_free(area); |
63 | 5.13k | } |
64 | | |
65 | | void memarea_free_without_callback(struct memarea **_area) |
66 | 0 | { |
67 | 0 | struct memarea *area = *_area; |
68 | |
|
69 | 0 | *_area = NULL; |
70 | 0 | i_assert(memarea_get_refcount(area) == 1); |
71 | 0 | i_free(area); |
72 | 0 | } |
73 | | |
74 | | unsigned int memarea_get_refcount(struct memarea *area) |
75 | 12 | { |
76 | 12 | i_assert(area->refcount > 0); |
77 | 12 | return area->refcount; |
78 | 12 | } |
79 | | |
80 | | const void *memarea_get(struct memarea *area, size_t *size_r) |
81 | 0 | { |
82 | 0 | *size_r = area->size; |
83 | 0 | return area->data; |
84 | 0 | } |
85 | | |
86 | | size_t memarea_get_size(struct memarea *area) |
87 | 0 | { |
88 | 0 | return area->size; |
89 | 0 | } |
90 | | |
91 | | void memarea_free_callback_noop(void *context ATTR_UNUSED) |
92 | 0 | { |
93 | 0 | } |