Coverage Report

Created: 2024-09-19 07:08

/src/fluent-bit/lib/monkey/mk_server/mk_clock.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
#include <stdio.h>
21
#include <stdlib.h>
22
#include <time.h>
23
24
#include <mk_core/mk_pthread.h>
25
#include <mk_core/mk_unistd.h>
26
27
#include <monkey/mk_core.h>
28
#include <monkey/mk_config.h>
29
#include <monkey/mk_clock.h>
30
#include <monkey/mk_utils.h>
31
#include <monkey/mk_tls.h>
32
33
#ifdef _WIN32
34
static struct tm* localtime_r(const time_t* timep, struct tm* result)
35
{
36
    localtime_s(result, timep);
37
38
    return result;
39
}
40
41
static struct tm* gmtime_r(const time_t* timep, struct tm* result)
42
{
43
    gmtime_s(result, timep);
44
45
    return result;
46
}
47
#endif
48
49
50
/*
51
 * The mk_ptr_ts have two buffers for avoid in half-way access from
52
 * another thread while a buffer is being modified. The function below returns
53
 * one of two buffers to work with.
54
 */
55
static inline char *_next_buffer(mk_ptr_t *pointer, char **buffers)
56
0
{
57
0
    if (pointer->data == buffers[0]) {
58
0
        return buffers[1];
59
0
    }
60
0
    else {
61
0
        return buffers[0];
62
0
    }
63
0
}
64
65
static void mk_clock_log_set_time(time_t utime, struct mk_server *server)
66
0
{
67
0
    char *time_string;
68
0
    struct tm result;
69
70
0
    time_string = _next_buffer(&server->clock_context->log_current_time, server->clock_context->log_time_buffers);
71
0
    server->clock_context->log_current_utime = utime;
72
73
0
    strftime(time_string, LOG_TIME_BUFFER_SIZE, "[%d/%b/%G %T %z]",
74
0
             localtime_r(&utime, &result));
75
76
0
    server->clock_context->log_current_time.data = time_string;
77
0
}
78
79
static void mk_clock_headers_preset(time_t utime, struct mk_server *server)
80
0
{
81
0
    int len1;
82
0
    int len2;
83
0
    struct tm *gmt_tm;
84
0
    struct tm result;
85
0
    char *buffer;
86
87
0
    buffer = _next_buffer(&server->clock_context->headers_preset,
88
0
                          server->clock_context->header_time_buffers);
89
90
0
    gmt_tm = gmtime_r(&utime, &result);
91
92
0
    len1 = snprintf(buffer,
93
0
                    HEADER_TIME_BUFFER_SIZE,
94
0
                    "%s",
95
0
                    server->server_signature_header);
96
97
0
    len2 = strftime(buffer + len1,
98
0
                    HEADER_PRESET_SIZE - len1,
99
0
                    MK_CLOCK_GMT_DATEFORMAT,
100
0
                    gmt_tm);
101
102
0
    server->clock_context->headers_preset.data = buffer;
103
0
    server->clock_context->headers_preset.len  = len1 + len2;
104
0
}
105
106
void *mk_clock_worker_init(void *data)
107
0
{
108
0
    time_t cur_time;
109
0
    struct mk_server *server = data;
110
111
0
    mk_utils_worker_rename("monkey: clock");
112
0
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
113
0
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
114
115
0
    server->clock_context->mk_clock_tid = pthread_self();
116
117
0
    while (1) {
118
0
        cur_time = time(NULL);
119
120
0
        if(cur_time != ((time_t)-1)) {
121
0
            mk_clock_log_set_time(cur_time, server);
122
0
            mk_clock_headers_preset(cur_time, server);
123
0
        }
124
0
        sleep(1);
125
0
    }
126
127
0
    return NULL;
128
0
}
129
130
void mk_clock_exit(struct mk_server *server)
131
0
{
132
0
    pthread_cancel(server->clock_context->mk_clock_tid);
133
0
    pthread_join(server->clock_context->mk_clock_tid, NULL);
134
135
0
    mk_mem_free(server->clock_context->header_time_buffers[0]);
136
0
    mk_mem_free(server->clock_context->header_time_buffers[1]);
137
0
    mk_mem_free(server->clock_context->log_time_buffers[0]);
138
0
    mk_mem_free(server->clock_context->log_time_buffers[1]);
139
140
0
    mk_mem_free(server->clock_context);
141
0
}
142
143
/* This function must be called before any threads are created */
144
void mk_clock_sequential_init(struct mk_server *server)
145
0
{
146
0
    server->clock_context = mk_mem_alloc_z(sizeof(struct mk_clock_context));
147
148
0
    if (server->clock_context == NULL) {
149
0
        return;
150
0
    }
151
152
    /* Time when monkey was started */
153
0
    server->clock_context->monkey_init_time = time(NULL);
154
155
0
    server->clock_context->log_current_time.len = LOG_TIME_BUFFER_SIZE - 2;
156
0
    server->clock_context->headers_preset.len = HEADER_PRESET_SIZE - 1;
157
158
0
    server->clock_context->header_time_buffers[0] = mk_mem_alloc_z(HEADER_PRESET_SIZE);
159
0
    server->clock_context->header_time_buffers[1] = mk_mem_alloc_z(HEADER_PRESET_SIZE);
160
161
0
    server->clock_context->log_time_buffers[0] = mk_mem_alloc_z(LOG_TIME_BUFFER_SIZE);
162
0
    server->clock_context->log_time_buffers[1] = mk_mem_alloc_z(LOG_TIME_BUFFER_SIZE);
163
164
    /* Set the time once */
165
0
    time_t cur_time = time(NULL);
166
167
0
    if (cur_time != ((time_t)-1)) {
168
0
        mk_clock_log_set_time(cur_time, server);
169
0
        mk_clock_headers_preset(cur_time, server);
170
0
    }
171
0
}