blob: 6367ac56fa7bb5443b7e6d915fa0c65adb9c8cac [file] [log] [blame]
Amaury Denoyellece444822021-03-25 15:09:38 +01001#include <stdio.h>
2#include <stdlib.h>
3
4#include <haproxy/init.h>
5#include <haproxy/list.h>
6
William Lallemandb53eb872022-04-21 18:02:53 +02007/* These functions are called just before a config validity check, which mean
8 * they are suited to use them in case we need to generate part of the
9 * configuration. It could be used for example to generate a proxy with
10 * multiple servers using the configuration parser itself. At this step the
11 * trash buffers are allocated.
12 * The functions must return 0 on success, or a combination
13 * of ERR_* flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause
14 * and immediate exit, so the function must have emitted any useful error.
15 */
16struct list pre_check_list = LIST_HEAD_INIT(pre_check_list);
17
Amaury Denoyellece444822021-03-25 15:09:38 +010018/* These functions are called just after the point where the program exits
19 * after a config validity check, so they are generally suited for resource
20 * allocation and slow initializations that should be skipped during basic
21 * config checks. The functions must return 0 on success, or a combination
22 * of ERR_* flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause
23 * and immediate exit, so the function must have emitted any useful error.
24 */
25struct list post_check_list = LIST_HEAD_INIT(post_check_list);
26
27/* These functions are called for each proxy just after the config validity
28 * check. The functions must return 0 on success, or a combination of ERR_*
29 * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
30 * exit, so the function must have emitted any useful error.
31 */
32struct list post_proxy_check_list = LIST_HEAD_INIT(post_proxy_check_list);
33
34/* These functions are called for each server just after the config validity
35 * check. The functions must return 0 on success, or a combination of ERR_*
36 * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
37 * exit, so the function must have emitted any useful error.
38 */
39struct list post_server_check_list = LIST_HEAD_INIT(post_server_check_list);
40
41/* These functions are called for each thread just after the thread creation
42 * and before running the init functions. They should be used to do per-thread
43 * (re-)allocations that are needed by subsequent functoins. They must return 0
44 * if an error occurred. */
45struct list per_thread_alloc_list = LIST_HEAD_INIT(per_thread_alloc_list);
46
47/* These functions are called for each thread just after the thread creation
48 * and before running the scheduler. They should be used to do per-thread
49 * initializations. They must return 0 if an error occurred. */
50struct list per_thread_init_list = LIST_HEAD_INIT(per_thread_init_list);
51
52/* These functions are called when freeing the global sections at the end of
53 * deinit, after everything is stopped. They don't return anything. They should
54 * not release shared resources that are possibly used by other deinit
55 * functions, only close/release what is private. Use the per_thread_free_list
56 * to release shared resources.
57 */
58struct list post_deinit_list = LIST_HEAD_INIT(post_deinit_list);
59
60/* These functions are called when freeing a proxy during the deinit, after
61 * everything isg stopped. They don't return anything. They should not release
62 * the proxy itself or any shared resources that are possibly used by other
63 * deinit functions, only close/release what is private.
64 */
65struct list proxy_deinit_list = LIST_HEAD_INIT(proxy_deinit_list);
66
67/* These functions are called when freeing a server during the deinit, after
68 * everything isg stopped. They don't return anything. They should not release
69 * the proxy itself or any shared resources that are possibly used by other
70 * deinit functions, only close/release what is private.
71 */
72struct list server_deinit_list = LIST_HEAD_INIT(server_deinit_list);
73
74/* These functions are called when freeing the global sections at the end of
75 * deinit, after the thread deinit functions, to release unneeded memory
76 * allocations. They don't return anything, and they work in best effort mode
77 * as their sole goal is to make valgrind mostly happy.
78 */
79struct list per_thread_free_list = LIST_HEAD_INIT(per_thread_free_list);
80
81/* These functions are called for each thread just after the scheduler loop and
82 * before exiting the thread. They don't return anything and, as for post-deinit
83 * functions, they work in best effort mode as their sole goal is to make
84 * valgrind mostly happy. */
85struct list per_thread_deinit_list = LIST_HEAD_INIT(per_thread_deinit_list);
86
William Lallemandb53eb872022-04-21 18:02:53 +020087/* used to register some initialization functions to call before the checks. */
88void hap_register_pre_check(int (*fct)())
89{
90 struct pre_check_fct *b;
91
92 b = calloc(1, sizeof(*b));
93 if (!b) {
94 fprintf(stderr, "out of memory\n");
95 exit(1);
96 }
97 b->fct = fct;
98 LIST_APPEND(&pre_check_list, &b->list);
99}
100
Amaury Denoyellece444822021-03-25 15:09:38 +0100101/* used to register some initialization functions to call after the checks. */
102void hap_register_post_check(int (*fct)())
103{
104 struct post_check_fct *b;
105
106 b = calloc(1, sizeof(*b));
107 if (!b) {
108 fprintf(stderr, "out of memory\n");
109 exit(1);
110 }
111 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200112 LIST_APPEND(&post_check_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100113}
114
115/* used to register some initialization functions to call for each proxy after
116 * the checks.
117 */
118void hap_register_post_proxy_check(int (*fct)(struct proxy *))
119{
120 struct post_proxy_check_fct *b;
121
122 b = calloc(1, sizeof(*b));
123 if (!b) {
124 fprintf(stderr, "out of memory\n");
125 exit(1);
126 }
127 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200128 LIST_APPEND(&post_proxy_check_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100129}
130
131/* used to register some initialization functions to call for each server after
132 * the checks.
133 */
134void hap_register_post_server_check(int (*fct)(struct server *))
135{
136 struct post_server_check_fct *b;
137
138 b = calloc(1, sizeof(*b));
139 if (!b) {
140 fprintf(stderr, "out of memory\n");
141 exit(1);
142 }
143 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200144 LIST_APPEND(&post_server_check_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100145}
146
147/* used to register some de-initialization functions to call after everything
148 * has stopped.
149 */
150void hap_register_post_deinit(void (*fct)())
151{
152 struct post_deinit_fct *b;
153
154 b = calloc(1, sizeof(*b));
155 if (!b) {
156 fprintf(stderr, "out of memory\n");
157 exit(1);
158 }
159 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200160 LIST_APPEND(&post_deinit_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100161}
162
163/* used to register some per proxy de-initialization functions to call after
164 * everything has stopped.
165 */
166void hap_register_proxy_deinit(void (*fct)(struct proxy *))
167{
168 struct proxy_deinit_fct *b;
169
170 b = calloc(1, sizeof(*b));
171 if (!b) {
172 fprintf(stderr, "out of memory\n");
173 exit(1);
174 }
175 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200176 LIST_APPEND(&proxy_deinit_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100177}
178
179/* used to register some per server de-initialization functions to call after
180 * everything has stopped.
181 */
182void hap_register_server_deinit(void (*fct)(struct server *))
183{
184 struct server_deinit_fct *b;
185
186 b = calloc(1, sizeof(*b));
187 if (!b) {
188 fprintf(stderr, "out of memory\n");
189 exit(1);
190 }
191 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200192 LIST_APPEND(&server_deinit_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100193}
194
195/* used to register some allocation functions to call for each thread. */
196void hap_register_per_thread_alloc(int (*fct)())
197{
198 struct per_thread_alloc_fct *b;
199
200 b = calloc(1, sizeof(*b));
201 if (!b) {
202 fprintf(stderr, "out of memory\n");
203 exit(1);
204 }
205 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200206 LIST_APPEND(&per_thread_alloc_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100207}
208
209/* used to register some initialization functions to call for each thread. */
210void hap_register_per_thread_init(int (*fct)())
211{
212 struct per_thread_init_fct *b;
213
214 b = calloc(1, sizeof(*b));
215 if (!b) {
216 fprintf(stderr, "out of memory\n");
217 exit(1);
218 }
219 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200220 LIST_APPEND(&per_thread_init_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100221}
222
223/* used to register some de-initialization functions to call for each thread. */
224void hap_register_per_thread_deinit(void (*fct)())
225{
226 struct per_thread_deinit_fct *b;
227
228 b = calloc(1, sizeof(*b));
229 if (!b) {
230 fprintf(stderr, "out of memory\n");
231 exit(1);
232 }
233 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200234 LIST_APPEND(&per_thread_deinit_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100235}
236
237/* used to register some free functions to call for each thread. */
238void hap_register_per_thread_free(void (*fct)())
239{
240 struct per_thread_free_fct *b;
241
242 b = calloc(1, sizeof(*b));
243 if (!b) {
244 fprintf(stderr, "out of memory\n");
245 exit(1);
246 }
247 b->fct = fct;
Willy Tarreau2b718102021-04-21 07:32:39 +0200248 LIST_APPEND(&per_thread_free_list, &b->list);
Amaury Denoyellece444822021-03-25 15:09:38 +0100249}