Coverage Report

Created: 2026-09-28 07:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/lib/monkey/mk_server/monkey.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  Monkey HTTP Server
4
 *  ==================
5
 *  Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#define _GNU_SOURCE
21
22
#include <mk_core/mk_pthread.h>
23
#include <mk_core/mk_event.h>
24
25
#include <monkey/mk_scheduler.h>
26
#include <monkey/mk_plugin.h>
27
#include <monkey/mk_clock.h>
28
#include <monkey/mk_thread.h>
29
#include <monkey/mk_mimetype.h>
30
#include <monkey/mk_http_thread.h>
31
#include <monkey/mk_tls_transport.h>
32
33
pthread_once_t mk_server_tls_setup_once = PTHREAD_ONCE_INIT;
34
35
static void mk_set_up_tls_keys()
36
0
{
37
0
    MK_INIT_INITIALIZE_TLS_UNIVERSAL();
38
0
    MK_INIT_INITIALIZE_TLS();
39
40
0
    mk_http_thread_initialize_tls();
41
0
}
42
43
void mk_server_info(struct mk_server *server)
44
0
{
45
0
    struct mk_list *head;
46
0
    struct mk_plugin *p;
47
0
    struct mk_config_listener *l;
48
49
#ifdef _WIN32
50
    printf(MK_BANNER_ENTRY "Process ID is %ld\n", (long)GetCurrentProcessId());
51
#else
52
0
    printf(MK_BANNER_ENTRY "Process ID is %ld\n", (long) getpid());
53
0
#endif
54
0
    mk_list_foreach(head, &server->listeners) {
55
0
        l = mk_list_entry(head, struct mk_config_listener, _head);
56
0
        printf(MK_BANNER_ENTRY "Server listening on %s:%s\n",
57
0
               l->address, l->port);
58
0
    }
59
0
    printf(MK_BANNER_ENTRY
60
0
           "%i threads, may handle up to %i client connections\n",
61
0
           server->workers, server->server_capacity);
62
63
    /* List loaded plugins */
64
0
    printf(MK_BANNER_ENTRY "Loaded Plugins: ");
65
0
    mk_list_foreach(head, &server->plugins) {
66
0
        p = mk_list_entry(head, struct mk_plugin, _head);
67
0
        printf("%s ", p->shortname);
68
0
    }
69
0
    printf("\n");
70
71
0
#ifdef __linux__
72
0
    char tmp[64];
73
74
0
    if (mk_kernel_features_print(tmp, sizeof(tmp), server) > 0) {
75
0
        printf(MK_BANNER_ENTRY "Linux Features: %s\n", tmp);
76
0
    }
77
0
#endif
78
79
0
    fflush(stdout);
80
0
}
81
82
/* Initialize Monkey Server */
83
struct mk_server *mk_server_create()
84
0
{
85
0
    int ret;
86
0
    int kern_version;
87
0
    int kern_features;
88
0
    struct mk_server *server;
89
90
0
    server = mk_mem_alloc_z(sizeof(struct mk_server));
91
0
    if (!server) {
92
0
        return NULL;
93
0
    }
94
95
    /* I'll try to leave both initializations here because 
96
     * it should be possible to run in windows using the accept
97
     * backend in which case it doesn't make sense to tie the net stack
98
     * initialization to libevent.
99
     */
100
0
    mk_net_init();
101
0
    mk_event_init();
102
103
    /* Library mode: event loop */
104
0
    server->lib_mode = MK_TRUE;
105
0
    server->lib_evl = mk_event_loop_create(8);
106
0
    if (!server->lib_evl) {
107
0
        mk_mem_free(server);
108
0
        return NULL;
109
0
    }
110
111
    /* Library mode: channel manager */
112
113
0
    memset(&server->lib_ch_event, 0, sizeof(struct mk_event));
114
115
0
    ret = mk_event_channel_create(server->lib_evl,
116
0
                                  &server->lib_ch_manager[0],
117
0
                                  &server->lib_ch_manager[1],
118
0
                                  &server->lib_ch_event);
119
120
0
    if (ret != 0) {
121
0
        mk_event_loop_destroy(server->lib_evl);
122
0
        mk_mem_free(server);
123
0
        return NULL;
124
0
    }
125
126
    /* Library mode: start event loop */
127
0
    server->lib_evl_start = mk_event_loop_create(1);
128
0
    if (!server->lib_evl_start) {
129
0
        mk_event_loop_destroy(server->lib_evl);
130
0
        mk_mem_free(server);
131
0
        return NULL;
132
0
    }
133
134
0
    memset(&server->lib_ch_start_event, 0, sizeof(struct mk_event));
135
136
0
    ret = mk_event_channel_create(server->lib_evl_start,
137
0
                                  &server->lib_ch_start[0],
138
0
                                  &server->lib_ch_start[1],
139
0
                                  &server->lib_ch_start_event);
140
141
0
    if (ret != 0) {
142
0
        mk_event_loop_destroy(server->lib_evl);
143
0
        mk_event_loop_destroy(server->lib_evl_start);
144
0
        mk_mem_free(server);
145
0
        return NULL;
146
0
    }
147
148
    /* Initialize linked list heads */
149
0
    mk_list_init(&server->plugins);
150
0
    mk_list_init(&server->sched_worker_callbacks);
151
0
    mk_list_init(&server->stage10_handler);
152
0
    mk_list_init(&server->stage20_handler);
153
0
    mk_list_init(&server->stage30_handler);
154
0
    mk_list_init(&server->stage40_handler);
155
0
    mk_list_init(&server->stage50_handler);
156
0
    server->scheduler_mode = -1;
157
158
0
    mk_core_init();
159
160
    /* Init thread keys */
161
0
    pthread_once(&mk_server_tls_setup_once, mk_set_up_tls_keys);
162
163
    /* Init Kernel version data */
164
0
    kern_version = mk_kernel_version();
165
0
    kern_features = mk_kernel_features(kern_version);
166
167
0
    server->kernel_version = kern_version;
168
0
    server->kernel_features = kern_features;
169
170
#ifdef MK_HAVE_TRACE
171
    MK_TRACE("Monkey TRACE is enabled");
172
    //pthread_mutex_init(&mutex_trace, (pthread_mutexattr_t *) NULL);
173
#endif
174
175
#ifdef LINUX_TRACE
176
    mk_info("Linux Trace enabled");
177
#endif
178
179
0
    mk_config_set_init_values(server);
180
181
0
    mk_mimetype_init(server);
182
183
0
    pthread_mutex_init(&server->vhost_fdt_mutex, NULL);
184
185
0
    return server;
186
0
}
187
188
/* Preserve the pthread-style clock entry point behind a void worker callback. */
189
static void mk_server_clock_worker(void *data)
190
0
{
191
0
    mk_clock_worker_init(data);
192
0
}
193
194
int mk_server_setup(struct mk_server *server)
195
0
{
196
0
    int ret;
197
0
    pthread_t tid;
198
199
    /* Core and Scheduler setup */
200
0
    mk_config_start_configure(server);
201
0
    if (server->path_conf_root != NULL && server->config == NULL) {
202
0
        return -1;
203
0
    }
204
205
0
    mk_config_signature(server);
206
0
    ret = mk_tls_init(server);
207
0
    if (ret != 0) {
208
0
        return -1;
209
0
    }
210
211
0
    mk_sched_init(server);
212
213
214
    /* Clock init that must happen before starting threads */
215
0
    mk_clock_sequential_init(server);
216
217
    /* Load plugins */
218
0
    mk_plugin_api_init(server);
219
0
    mk_plugin_load_all(server);
220
221
    /* Workers: logger and clock */
222
0
    ret = mk_utils_worker_spawn(mk_server_clock_worker, server, &tid);
223
0
    if (ret != 0) {
224
0
        return -1;
225
0
    }
226
227
    /* Configuration sanity check */
228
0
    mk_config_sanity_check(server);
229
230
    /* Invoke Plugin PRCTX hooks */
231
0
    mk_plugin_core_process(server);
232
233
    /* Launch monkey http workers */
234
0
    mk_server_launch_workers(server);
235
236
0
    return 0;
237
0
}
238
239
void mk_exit_all(struct mk_server *server)
240
0
{
241
0
    uint64_t val;
242
243
    /* Distribute worker signals to stop working */
244
0
    val = MK_SCHED_SIGNAL_FREE_ALL;
245
0
    mk_sched_broadcast_signal(server, val);
246
247
    /* Wait for all workers to finish */
248
0
    mk_sched_workers_join(server);
249
250
    /* Continue exiting */
251
0
    mk_plugin_exit_all(server);
252
0
    mk_tls_exit(server);
253
0
    mk_clock_exit(server);
254
255
0
    mk_sched_exit(server);
256
0
    if (server->lib_evl != NULL) {
257
0
        mk_event_loop_destroy(server->lib_evl);
258
0
        server->lib_evl = NULL;
259
0
    }
260
0
    if (server->lib_evl_start != NULL) {
261
0
        mk_event_loop_destroy(server->lib_evl_start);
262
        server->lib_evl_start = NULL;
263
0
    }
264
0
    pthread_mutex_destroy(&server->vhost_fdt_mutex);
265
0
    mk_config_free_all(server);
266
0
}