Coverage Report

Created: 2025-07-12 06:16

/src/unit/src/nxt_log_moderation.c
Line
Count
Source (jump to first uncovered line)
1
2
/*
3
 * Copyright (C) Igor Sysoev
4
 * Copyright (C) NGINX, Inc.
5
 */
6
7
#include <nxt_main.h>
8
9
10
static void nxt_log_moderate_timer_handler(nxt_task_t *task, void *obj,
11
    void *data);
12
13
14
nxt_bool_t
15
nxt_log_moderate_allow(nxt_log_moderation_t *mod)
16
0
{
17
0
    nxt_uint_t    n;
18
0
    nxt_time_t    now;
19
0
    nxt_bool_t    allow, timer;
20
0
    nxt_thread_t  *thr;
21
22
0
    thr = nxt_thread();
23
0
    now = nxt_thread_time(thr);
24
25
0
    allow = 0;
26
0
    timer = 0;
27
28
0
    nxt_thread_spin_lock(&mod->lock);
29
30
0
    n = mod->count++;
31
32
0
    if (now != mod->last) {
33
34
0
        if (n <= mod->limit) {
35
0
            mod->last = now;
36
0
            mod->count = 1;
37
0
            allow = 1;
38
0
        }
39
40
        /* "n > mod->limit" means that timer has already been set. */
41
42
0
    } else {
43
44
0
        if (n < mod->limit) {
45
0
            allow = 1;
46
47
0
        } else if (n == mod->limit) {
48
            /*
49
             * There is a race condition on 32-bit many core system
50
             * capable to fail an operation 2^32 times per second.
51
             * This can be fixed by storing mod->count as uint64_t.
52
             */
53
0
            timer = 1;
54
0
            mod->pid = nxt_pid;
55
0
        }
56
0
    }
57
58
0
    nxt_thread_spin_unlock(&mod->lock);
59
60
0
    if (timer) {
61
0
        mod->timer.work_queue = &thr->engine->fast_work_queue;
62
0
        mod->timer.handler = nxt_log_moderate_timer_handler;
63
0
        mod->timer.log = &nxt_main_log;
64
0
        mod->timer.task = &nxt_main_task;
65
66
0
        nxt_timer_add(thr->engine, &mod->timer, 1000);
67
0
    }
68
69
0
    return allow;
70
0
}
71
72
73
static void
74
nxt_log_moderate_timer_handler(nxt_task_t *task, void *obj, void *data)
75
0
{
76
0
    nxt_bool_t            msg;
77
0
    nxt_timer_t           *ev;
78
0
    nxt_atomic_uint_t     n;
79
0
    nxt_log_moderation_t  *mod;
80
81
0
    ev = obj;
82
0
    mod = nxt_timer_data(ev, nxt_log_moderation_t, timer);
83
84
0
    nxt_thread_spin_lock(&mod->lock);
85
86
0
    mod->last = nxt_thread_time(task->thread);
87
0
    n = mod->count;
88
0
    mod->count = 0;
89
0
    msg = (mod->pid == nxt_pid);
90
91
0
    nxt_thread_spin_unlock(&mod->lock);
92
93
0
    if (msg) {
94
0
        nxt_log_error(mod->level, &nxt_main_log, "%s %uA times",
95
0
                      mod->msg, n - mod->limit);
96
0
    }
97
0
}