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
nxt_log_moderate_allow(nxt_log_moderation_t * mod)15 nxt_log_moderate_allow(nxt_log_moderation_t *mod)
16 {
17 nxt_uint_t n;
18 nxt_time_t now;
19 nxt_bool_t allow, timer;
20 nxt_thread_t *thr;
21
22 thr = nxt_thread();
23 now = nxt_thread_time(thr);
24
25 allow = 0;
26 timer = 0;
27
28 nxt_thread_spin_lock(&mod->lock);
29
30 n = mod->count++;
31
32 if (now != mod->last) {
33
34 if (n <= mod->limit) {
35 mod->last = now;
36 mod->count = 1;
37 allow = 1;
38 }
39
40 /* "n > mod->limit" means that timer has already been set. */
41
42 } else {
43
44 if (n < mod->limit) {
45 allow = 1;
46
47 } 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 timer = 1;
54 mod->pid = nxt_pid;
55 }
56 }
57
58 nxt_thread_spin_unlock(&mod->lock);
59
60 if (timer) {
61 mod->timer.work_queue = &thr->engine->fast_work_queue;
62 mod->timer.handler = nxt_log_moderate_timer_handler;
63 mod->timer.log = &nxt_main_log;
64 mod->timer.task = &nxt_main_task;
65
66 nxt_timer_add(thr->engine, &mod->timer, 1000);
67 }
68
69 return allow;
70 }
71
72
73 static void
nxt_log_moderate_timer_handler(nxt_task_t * task,void * obj,void * data)74 nxt_log_moderate_timer_handler(nxt_task_t *task, void *obj, void *data)
75 {
76 nxt_bool_t msg;
77 nxt_timer_t *ev;
78 nxt_atomic_uint_t n;
79 nxt_log_moderation_t *mod;
80
81 ev = obj;
82 mod = nxt_timer_data(ev, nxt_log_moderation_t, timer);
83
84 nxt_thread_spin_lock(&mod->lock);
85
86 mod->last = nxt_thread_time(task->thread);
87 n = mod->count;
88 mod->count = 0;
89 msg = (mod->pid == nxt_pid);
90
91 nxt_thread_spin_unlock(&mod->lock);
92
93 if (msg) {
94 nxt_log_error(mod->level, &nxt_main_log, "%s %uA times",
95 mod->msg, n - mod->limit);
96 }
97 }
98