/src/dovecot/src/lib/mempool-unsafe-datastack.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ |
2 | | |
3 | | #include "lib.h" |
4 | | #include "mempool.h" |
5 | | |
6 | | /* |
7 | | * The unsafe datastack pool is a very thin wrapper around the datastack |
8 | | * API. It is a simpler version of the datastack pool that does not do any |
9 | | * sanity checking, it simply forwards the calls to the datastack API. It |
10 | | * exists to allow some internal APIs to make datastack allocations via the |
11 | | * pool API. |
12 | | * |
13 | | * Note to consumers: Consider using the (safe) datastack pool instead of |
14 | | * this one. |
15 | | * |
16 | | * Implementation |
17 | | * ============== |
18 | | * |
19 | | * Creation |
20 | | * -------- |
21 | | * |
22 | | * The unsafe datastack pool is created statically and therefore is |
23 | | * available at any time after the datastack allocator is initialized. |
24 | | * |
25 | | * Allocation & Reallocation |
26 | | * ------------------------- |
27 | | * |
28 | | * The p_malloc() and p_realloc() calls get directed to t_malloc0() and |
29 | | * t_try_realloc(), respectively. There is no additional per-allocation |
30 | | * information to track. |
31 | | * |
32 | | * Freeing |
33 | | * ------- |
34 | | * |
35 | | * A no-op. |
36 | | * |
37 | | * Clearing |
38 | | * -------- |
39 | | * |
40 | | * A no-op. |
41 | | * |
42 | | * Destruction |
43 | | * ----------- |
44 | | * |
45 | | * It is not possible to destroy the unsafe datastack pool. Any attempt to |
46 | | * unref the pool is a no-op. |
47 | | */ |
48 | | |
49 | | static const char *pool_unsafe_data_stack_get_name(pool_t pool); |
50 | | static void pool_unsafe_data_stack_ref(pool_t pool); |
51 | | static void pool_unsafe_data_stack_unref(pool_t *pool); |
52 | | static void *pool_unsafe_data_stack_malloc(pool_t pool, size_t size); |
53 | | static void pool_unsafe_data_stack_free(pool_t pool, void *mem); |
54 | | static void *pool_unsafe_data_stack_realloc(pool_t pool, void *mem, |
55 | | size_t old_size, size_t new_size); |
56 | | static void pool_unsafe_data_stack_clear(pool_t pool); |
57 | | static size_t pool_unsafe_data_stack_get_max_easy_alloc_size(pool_t pool); |
58 | | |
59 | | static struct pool_vfuncs static_unsafe_data_stack_pool_vfuncs = { |
60 | | pool_unsafe_data_stack_get_name, |
61 | | |
62 | | pool_unsafe_data_stack_ref, |
63 | | pool_unsafe_data_stack_unref, |
64 | | |
65 | | pool_unsafe_data_stack_malloc, |
66 | | pool_unsafe_data_stack_free, |
67 | | |
68 | | pool_unsafe_data_stack_realloc, |
69 | | |
70 | | pool_unsafe_data_stack_clear, |
71 | | pool_unsafe_data_stack_get_max_easy_alloc_size |
72 | | }; |
73 | | |
74 | | static struct pool static_unsafe_data_stack_pool = { |
75 | | .v = &static_unsafe_data_stack_pool_vfuncs, |
76 | | |
77 | | .alloconly_pool = TRUE, |
78 | | .datastack_pool = TRUE |
79 | | }; |
80 | | |
81 | | pool_t unsafe_data_stack_pool = &static_unsafe_data_stack_pool; |
82 | | |
83 | | static const char *pool_unsafe_data_stack_get_name(pool_t pool ATTR_UNUSED) |
84 | 0 | { |
85 | 0 | return "unsafe data stack"; |
86 | 0 | } |
87 | | |
88 | | static void pool_unsafe_data_stack_ref(pool_t pool ATTR_UNUSED) |
89 | 0 | { |
90 | 0 | } |
91 | | |
92 | | static void pool_unsafe_data_stack_unref(pool_t *pool ATTR_UNUSED) |
93 | 0 | { |
94 | 0 | } |
95 | | |
96 | | static void *pool_unsafe_data_stack_malloc(pool_t pool ATTR_UNUSED, |
97 | | size_t size) |
98 | 103k | { |
99 | 103k | return t_malloc0(size); |
100 | 103k | } |
101 | | |
102 | | static void pool_unsafe_data_stack_free(pool_t pool ATTR_UNUSED, |
103 | | void *mem ATTR_UNUSED) |
104 | 0 | { |
105 | 0 | } |
106 | | |
107 | | static void *pool_unsafe_data_stack_realloc(pool_t pool ATTR_UNUSED, |
108 | | void *mem, |
109 | | size_t old_size, size_t new_size) |
110 | 4.14k | { |
111 | 4.14k | void *new_mem; |
112 | | |
113 | | /* @UNSAFE */ |
114 | 4.14k | if (old_size >= new_size) |
115 | 0 | return mem; |
116 | | |
117 | 4.14k | if (!t_try_realloc(mem, new_size)) { |
118 | 126 | new_mem = t_malloc_no0(new_size); |
119 | 126 | if (old_size > 0) |
120 | 126 | memcpy(new_mem, mem, old_size); |
121 | 126 | mem = new_mem; |
122 | 126 | } |
123 | | |
124 | 4.14k | memset((char *) mem + old_size, 0, new_size - old_size); |
125 | 4.14k | return mem; |
126 | 4.14k | } |
127 | | |
128 | | static void pool_unsafe_data_stack_clear(pool_t pool ATTR_UNUSED) |
129 | 0 | { |
130 | 0 | } |
131 | | |
132 | | static size_t |
133 | | pool_unsafe_data_stack_get_max_easy_alloc_size(pool_t pool ATTR_UNUSED) |
134 | 0 | { |
135 | 0 | return t_get_bytes_available(); |
136 | 0 | } |