Coverage Report

Created: 2023-03-10 07:33

/src/fluent-bit/lib/monkey/mk_server/monkey.c
Line
Count
Source (jump to first uncovered line)
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
32
pthread_once_t mk_server_tls_setup_once = PTHREAD_ONCE_INIT;
33
34
static void mk_set_up_tls_keys()
35
0
{
36
0
    MK_INIT_INITIALIZE_TLS_UNIVERSAL();
37
0
    MK_INIT_INITIALIZE_TLS();
38
39
0
    mk_http_thread_initialize_tls();
40
0
}
41
42
void mk_server_info(struct mk_server *server)
43
0
{
44
0
    struct mk_list *head;
45
0
    struct mk_plugin *p;
46
0
    struct mk_config_listener *l;
47
48
#ifdef _WIN32
49
    printf(MK_BANNER_ENTRY "Process ID is %ld\n", (long)GetCurrentProcessId());
50
#else
51
0
    printf(MK_BANNER_ENTRY "Process ID is %ld\n", (long) getpid());
52
0
#endif
53
0
    mk_list_foreach(head, &server->listeners) {
54
0
        l = mk_list_entry(head, struct mk_config_listener, _head);
55
0
        printf(MK_BANNER_ENTRY "Server listening on %s:%s\n",
56
0
               l->address, l->port);
57
0
    }
58
0
    printf(MK_BANNER_ENTRY
59
0
           "%i threads, may handle up to %i client connections\n",
60
0
           server->workers, server->server_capacity);
61
62
    /* List loaded plugins */
63
0
    printf(MK_BANNER_ENTRY "Loaded Plugins: ");
64
0
    mk_list_foreach(head, &server->plugins) {
65
0
        p = mk_list_entry(head, struct mk_plugin, _head);
66
0
        printf("%s ", p->shortname);
67
0
    }
68
0
    printf("\n");
69
70
0
#ifdef __linux__
71
0
    char tmp[64];
72
73
0
    if (mk_kernel_features_print(tmp, sizeof(tmp), server) > 0) {
74
0
        printf(MK_BANNER_ENTRY "Linux Features: %s\n", tmp);
75
0
    }
76
0
#endif
77
78
0
    fflush(stdout);
79
0
}
80
81
/* Initialize Monkey Server */
82
struct mk_server *mk_server_create()
83
0
{
84
0
    int ret;
85
0
    int kern_version;
86
0
    int kern_features;
87
0
    struct mk_server *server;
88
89
0
    server = mk_mem_alloc_z(sizeof(struct mk_server));
90
0
    if (!server) {
91
0
        return NULL;
92
0
    }
93
94
    /* I'll try to leave both initializations here because 
95
     * it should be possible to run in windows using the accept
96
     * backend in which case it doesn't make sense to tie the net stack
97
     * initialization to libevent.
98
     */
99
0
    mk_net_init();
100
0
    mk_event_init();
101
102
    /* Library mode: event loop */
103
0
    server->lib_mode = MK_TRUE;
104
0
    server->lib_evl = mk_event_loop_create(8);
105
0
    if (!server->lib_evl) {
106
0
        mk_mem_free(server);
107
0
        return NULL;
108
0
    }
109
110
    /* Library mode: channel manager */
111
112
0
    memset(&server->lib_ch_event, 0, sizeof(struct mk_event));
113
114
0
    ret = mk_event_channel_create(server->lib_evl,
115
0
                                  &server->lib_ch_manager[0],
116
0
                                  &server->lib_ch_manager[1],
117
0
                                  &server->lib_ch_event);
118
119
0
    if (ret != 0) {
120
0
        mk_event_loop_destroy(server->lib_evl);
121
0
        mk_mem_free(server);
122
0
        return NULL;
123
0
    }
124
125
    /* Library mode: start event loop */
126
0
    server->lib_evl_start = mk_event_loop_create(1);
127
0
    if (!server->lib_evl_start) {
128
0
        mk_event_loop_destroy(server->lib_evl);
129
0
        mk_mem_free(server);
130
0
        return NULL;
131
0
    }
132
133
0
    memset(&server->lib_ch_start_event, 0, sizeof(struct mk_event));
134
135
0
    ret = mk_event_channel_create(server->lib_evl_start,
136
0
                                  &server->lib_ch_start[0],
137
0
                                  &server->lib_ch_start[1],
138
0
                                  &server->lib_ch_start_event);
139
140
0
    if (ret != 0) {
141
0
        mk_event_loop_destroy(server->lib_evl);
142
0
        mk_event_loop_destroy(server->lib_evl_start);
143
0
        mk_mem_free(server);
144
0
        return NULL;
145
0
    }
146
147
    /* Initialize linked list heads */
148
0
    mk_list_init(&server->plugins);
149
0
    mk_list_init(&server->sched_worker_callbacks);
150
0
    mk_list_init(&server->stage10_handler);
151
0
    mk_list_init(&server->stage20_handler);
152
0
    mk_list_init(&server->stage30_handler);
153
0
    mk_list_init(&server->stage40_handler);
154
0
    mk_list_init(&server->stage50_handler);
155
0
    server->scheduler_mode = -1;
156
157
0
    mk_core_init();
158
159
    /* Init thread keys */
160
0
    pthread_once(&mk_server_tls_setup_once, mk_set_up_tls_keys);
161
162
    /* Init Kernel version data */
163
0
    kern_version = mk_kernel_version();
164
0
    kern_features = mk_kernel_features(kern_version);
165
166
0
    server->kernel_version = kern_version;
167
0
    server->kernel_features = kern_features;
168
169
#ifdef MK_HAVE_TRACE
170
    MK_TRACE("Monkey TRACE is enabled");
171
    //pthread_mutex_init(&mutex_trace, (pthread_mutexattr_t *) NULL);
172
#endif
173
174
#ifdef LINUX_TRACE
175
    mk_info("Linux Trace enabled");
176
#endif
177
178
0
    mk_config_set_init_values(server);
179
180
0
    mk_mimetype_init(server);
181
182
0
    pthread_mutex_init(&server->vhost_fdt_mutex, NULL);
183
184
0
    return server;
185
0
}
186
187
int mk_server_setup(struct mk_server *server)
188
0
{
189
0
    int ret;
190
0
    pthread_t tid;
191
192
    /* Core and Scheduler setup */
193
0
    mk_config_start_configure(server);
194
0
    mk_config_signature(server);
195
196
0
    mk_sched_init(server);
197
198
199
    /* Clock init that must happen before starting threads */
200
0
    mk_clock_sequential_init(server);
201
202
    /* Load plugins */
203
0
    mk_plugin_api_init();
204
0
    mk_plugin_load_all(server);
205
206
    /* Workers: logger and clock */
207
0
    ret = mk_utils_worker_spawn((void *) mk_clock_worker_init, server, &tid);
208
0
    if (ret != 0) {
209
0
        return -1;
210
0
    }
211
212
    /* Configuration sanity check */
213
0
    mk_config_sanity_check(server);
214
215
    /* Invoke Plugin PRCTX hooks */
216
0
    mk_plugin_core_process(server);
217
218
    /* Launch monkey http workers */
219
0
    mk_server_launch_workers(server);
220
221
0
    return 0;
222
0
}
223
224
void mk_exit_all(struct mk_server *server)
225
0
{
226
0
    uint64_t val;
227
228
    /* Distribute worker signals to stop working */
229
0
    val = MK_SCHED_SIGNAL_FREE_ALL;
230
0
    mk_sched_broadcast_signal(server, val);
231
232
    /* Wait for all workers to finish */
233
0
    mk_sched_workers_join(server);
234
235
    /* Continue exiting */
236
0
    mk_plugin_exit_all(server);
237
0
    mk_clock_exit();
238
239
0
    mk_sched_exit(server);
240
0
    mk_config_free_all(server);
241
0
}