struct hashmap* rules_hashmap = NULL;
/* Keep rules table as single-linked list */
-struct rule* rules_table = NULL;
+struct rule* current_rules_table = NULL;
+struct rule* original_rules_table = NULL;
#define HASHMAP_MASK(hm) ((int)(hm->size - 1))
#define HASHMAP_LINEAR_PROBE_LEAP 1
}
/* Must be always executed after __log_config_read() */
-int __log_limiter_initialize(void)
+int __log_limiter_initialize(struct rule *rules_table)
{
int hm_size;
struct rule* rlist = NULL;
rules_hashmap = (struct hashmap*) hashmap_create(hm_size,
&rule_compare,
&rule_match);
- if (NULL == rules_hashmap || !rules_hashmap->size)
- goto bailout;
+ if (NULL == rules_hashmap || !rules_hashmap->size) {
+ hashmap_destroy(&rules_hashmap);
+ return -1;
+ }
/* Add rule to hashmap */
rlist = rules_table;
}
return 0;
-
-bailout:
- hashmap_destroy(&rules_hashmap);
- rules_destroy(&rules_table);
-
- return (-1);
}
// LCOV_EXCL_STOP
void __log_limiter_destroy(void)
{
hashmap_destroy(&rules_hashmap);
- rules_destroy(&rules_table);
+ rules_destroy(&original_rules_table);
}
// LCOV_EXCL_START
-int __log_limiter_add_rule(const char* tag, int prio, int limit)
+int __log_limiter_add_rule(struct rule** rules_table, const char* tag, int prio, int limit)
{
struct rule* r;
if (!tag)
return (-1);
- for (struct rule *i = rules_table; i; i = i->prev) {
+ for (struct rule *i = *rules_table; i; i = i->prev) {
if (strcmp(i->tag, tag) || i->prio != util_prio_to_char(prio))
continue;
r->start = time(NULL);
r->hit = 0;
- r->prev = rules_table;
- rules_table = r;
+ r->prev = *rules_table;
+ *rules_table = r;
return 0;
}
* @param[in,out] u Userdata (unused)
*/
// LCOV_EXCL_START
-static void __config_iteration(const char* key, const char* value, void *u)
+static void __config_iteration(const char* key, const char* value, void *userdata)
{
assert(key);
assert(value);
+ struct rule **rules_table = (struct rule **)userdata;
+ assert(rules_table);
static const int prefix_len = sizeof("limiter|") - 1;
char * delimiter_pos;
else
limit = atoi(value);
- __log_limiter_add_rule(limiter_tag, *(delimiter_pos + 1), limit);
+ __log_limiter_add_rule(rules_table, limiter_tag, *(delimiter_pos + 1), limit);
}
// LCOV_EXCL_STOP
int __log_limiter_create(struct log_config *config)
{
assert(config);
- assert(!rules_table);
+ assert(!original_rules_table);
assert(!rules_hashmap);
- log_config_foreach(config, __config_iteration, NULL); // LCOV_EXCL_LINE
+ log_config_foreach(config, __config_iteration, &original_rules_table); // LCOV_EXCL_LINE
+
+ const int r = __log_limiter_initialize(original_rules_table); // LCOV_EXCL_LINE
+ if (r)
+ rules_destroy(&original_rules_table);
+ return !r;
+}
+
+void __log_limiter_update(struct log_config *config)
+{
+ assert(config);
+ assert(!original_rules_table || rules_hashmap);
+
+ struct rule *rules_table = NULL;
+ for (struct rule *i = original_rules_table; i; i = i->prev)
+ __log_limiter_add_rule(&rules_table, i->tag, i->prio, i->limit);
+
+ log_config_foreach(config, __config_iteration, &rules_table);
+
+ if (rules_hashmap) {
+ for (struct rule *i = rules_table; i; i = i->prev) {
+ const char prio_c = util_prio_to_char(i->prio);
+ const struct rule *const prev_rule = hashmap_search(rules_hashmap, i->tag, prio_c);
+ if (!prev_rule)
+ continue;
+
+ i->hit = prev_rule->hit;
+ i->start = prev_rule->start;
+ }
+ }
+
+ hashmap_destroy(&rules_hashmap);
+ __log_limiter_initialize(rules_table);
- return (__log_limiter_initialize() == 0); // LCOV_EXCL_LINE
+ rules_destroy(¤t_rules_table);
+ current_rules_table = rules_table;
}