summaryrefslogtreecommitdiffstats
path: root/src/init.c
blob: 6367ac56fa7bb5443b7e6d915fa0c65adb9c8cac (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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#include <stdio.h>
#include <stdlib.h>

#include <haproxy/init.h>
#include <haproxy/list.h>

/* These functions are called just before a config validity check, which mean
 * they are suited to use them in case we need to generate part of the
 * configuration. It could be used for example to generate a proxy with
 * multiple servers using the configuration parser itself. At this step the
 * trash buffers are allocated.
 * The functions must return 0 on success, or a combination
 * of ERR_* flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause
 * and immediate exit, so the function must have emitted any useful error.
 */
struct list pre_check_list = LIST_HEAD_INIT(pre_check_list);

/* These functions are called just after the point where the program exits
 * after a config validity check, so they are generally suited for resource
 * allocation and slow initializations that should be skipped during basic
 * config checks. The functions must return 0 on success, or a combination
 * of ERR_* flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause
 * and immediate exit, so the function must have emitted any useful error.
 */
struct list post_check_list = LIST_HEAD_INIT(post_check_list);

/* These functions are called for each proxy just after the config validity
 * check. The functions must return 0 on success, or a combination of ERR_*
 * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
 * exit, so the function must have emitted any useful error.
 */
struct list post_proxy_check_list = LIST_HEAD_INIT(post_proxy_check_list);

/* These functions are called for each server just after the config validity
 * check. The functions must return 0 on success, or a combination of ERR_*
 * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
 * exit, so the function must have emitted any useful error.
 */
struct list post_server_check_list = LIST_HEAD_INIT(post_server_check_list);

/* These functions are called for each thread just after the thread creation
 * and before running the init functions. They should be used to do per-thread
 * (re-)allocations that are needed by subsequent functoins. They must return 0
 * if an error occurred. */
struct list per_thread_alloc_list = LIST_HEAD_INIT(per_thread_alloc_list);

/* These functions are called for each thread just after the thread creation
 * and before running the scheduler. They should be used to do per-thread
 * initializations. They must return 0 if an error occurred. */
struct list per_thread_init_list = LIST_HEAD_INIT(per_thread_init_list);

/* These functions are called when freeing the global sections at the end of
 * deinit, after everything is stopped. They don't return anything. They should
 * not release shared resources that are possibly used by other deinit
 * functions, only close/release what is private. Use the per_thread_free_list
 * to release shared resources.
 */
struct list post_deinit_list = LIST_HEAD_INIT(post_deinit_list);

/* These functions are called when freeing a proxy during the deinit, after
 * everything isg stopped. They don't return anything. They should not release
 * the proxy itself or any shared resources that are possibly used by other
 * deinit functions, only close/release what is private.
 */
struct list proxy_deinit_list = LIST_HEAD_INIT(proxy_deinit_list);

/* These functions are called when freeing a server during the deinit, after
 * everything isg stopped. They don't return anything. They should not release
 * the proxy itself or any shared resources that are possibly used by other
 * deinit functions, only close/release what is private.
 */
struct list server_deinit_list = LIST_HEAD_INIT(server_deinit_list);

/* These functions are called when freeing the global sections at the end of
 * deinit, after the thread deinit functions, to release unneeded memory
 * allocations. They don't return anything, and they work in best effort mode
 * as their sole goal is to make valgrind mostly happy.
 */
struct list per_thread_free_list = LIST_HEAD_INIT(per_thread_free_list);

/* These functions are called for each thread just after the scheduler loop and
 * before exiting the thread. They don't return anything and, as for post-deinit
 * functions, they work in best effort mode as their sole goal is to make
 * valgrind mostly happy. */
struct list per_thread_deinit_list = LIST_HEAD_INIT(per_thread_deinit_list);

/* used to register some initialization functions to call before the checks. */
void hap_register_pre_check(int (*fct)())
{
	struct pre_check_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&pre_check_list, &b->list);
}

/* used to register some initialization functions to call after the checks. */
void hap_register_post_check(int (*fct)())
{
	struct post_check_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&post_check_list, &b->list);
}

/* used to register some initialization functions to call for each proxy after
 * the checks.
 */
void hap_register_post_proxy_check(int (*fct)(struct proxy *))
{
	struct post_proxy_check_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&post_proxy_check_list, &b->list);
}

/* used to register some initialization functions to call for each server after
 * the checks.
 */
void hap_register_post_server_check(int (*fct)(struct server *))
{
	struct post_server_check_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&post_server_check_list, &b->list);
}

/* used to register some de-initialization functions to call after everything
 * has stopped.
 */
void hap_register_post_deinit(void (*fct)())
{
	struct post_deinit_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&post_deinit_list, &b->list);
}

/* used to register some per proxy de-initialization functions to call after
 * everything has stopped.
 */
void hap_register_proxy_deinit(void (*fct)(struct proxy *))
{
	struct proxy_deinit_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&proxy_deinit_list, &b->list);
}

/* used to register some per server de-initialization functions to call after
 * everything has stopped.
 */
void hap_register_server_deinit(void (*fct)(struct server *))
{
	struct server_deinit_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&server_deinit_list, &b->list);
}

/* used to register some allocation functions to call for each thread. */
void hap_register_per_thread_alloc(int (*fct)())
{
	struct per_thread_alloc_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&per_thread_alloc_list, &b->list);
}

/* used to register some initialization functions to call for each thread. */
void hap_register_per_thread_init(int (*fct)())
{
	struct per_thread_init_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&per_thread_init_list, &b->list);
}

/* used to register some de-initialization functions to call for each thread. */
void hap_register_per_thread_deinit(void (*fct)())
{
	struct per_thread_deinit_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&per_thread_deinit_list, &b->list);
}

/* used to register some free functions to call for each thread. */
void hap_register_per_thread_free(void (*fct)())
{
	struct per_thread_free_fct *b;

	b = calloc(1, sizeof(*b));
	if (!b) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	b->fct = fct;
	LIST_APPEND(&per_thread_free_list, &b->list);
}