Make the limiter a self-contained struct 14/258014/5
authorMateusz Majewski <m.majewski2@samsung.com>
Fri, 26 Mar 2021 14:20:36 +0000 (15:20 +0100)
committerMateusz Majewski <m.majewski2@samsung.com>
Tue, 25 May 2021 13:41:56 +0000 (15:41 +0200)
Change-Id: Ic2abf2da2b9e51b596e5612d9ac65044cf4540c4

14 files changed:
include/dynamic_config.h
include/loglimiter-internal.h
include/loglimiter.h
src/libdlog/dynamic_config.c
src/libdlog/log.c
src/logctl/logctl.c
src/shared/loglimiter.c
src/tests/dynamic_config.c
src/tests/libdlog_base_wrap.c
src/tests/libdlog_prio_filter_pos.c
src/tests/limiter_neg.c
src/tests/limiter_pos.c
src/tests/limiter_wrap.c
src/tests/pid_limiter.c

index 3027056..de1fb63 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <loglimiter.h>
+
 /*  MIT License
  *
  * Copyright (c) 2018-2020 Samsung Electronics Co., Ltd
@@ -35,7 +37,7 @@ extern "C" {
 
 bool __dynamic_config_create(struct log_config *config);
 void __dynamic_config_destroy(void);
-void __dynamic_config_update(void);
+void __dynamic_config_update(struct limiter_data *limiter_data);;
 
 #ifdef __cplusplus
 }
index c89dcb2..f0effbd 100644 (file)
@@ -21,7 +21,31 @@ struct rule {
        enum rule_type type;
 };
 
-int __log_limiter_initialize(struct rule *rules_table);
+typedef int (*hash_cmp_func_t)(struct rule *, struct rule *);
+typedef int (*hash_match_func_t)(struct rule *, unsigned, const char *, int);
+
+struct hashmap {
+       hash_cmp_func_t cmp;
+       hash_match_func_t match;
+       int size;
+       void *bucket[];
+};
+
+struct limiter_data {
+       pid_t prev_pid;
+       size_t sent_by_me;
+       bool already_exceeded;
+       time_t last_pid_time;
+       struct pid_limit *cached_pid_rule;
+       list_head pid_rules;
+       time_t refresh_rate_s;
+       struct rule *current_rules_table;
+       struct rule *original_rules_table;
+       struct hashmap *rules_hashmap;
+
+};
+
+int __log_limiter_initialize(struct limiter_data *limiter_data, struct rule *rules_table);
 uint32_t util_hash_key(const char *s, int c);
 
 #endif // LOGLIMITER_INTERNAL_H_
index bb41008..d66c6a6 100644 (file)
@@ -37,6 +37,7 @@ extern "C" {
 #include <ptrs_list.h>
 
 struct rule;
+struct limiter_data;
 
 struct limiter_limits {
        int tag_and_prio;
@@ -50,7 +51,7 @@ struct pid_limit {
        size_t limit;
 };
 
-void __log_limiter_destroy(void);
+void __log_limiter_destroy(struct limiter_data *limiter_data);
 
 struct pass_log_result {
        enum {
@@ -64,18 +65,18 @@ struct pass_log_result {
        int period_s;
 };
 
-struct pass_log_result __log_limiter_pass_log(const char *tag, int prio);
+struct pass_log_result __log_limiter_pass_log(struct limiter_data *limiter_data, const char *tag, int prio);
 
-int __log_limiter_create(const struct log_config *config);
+struct limiter_data *__log_limiter_create(const struct log_config *config);
 
-struct limiter_limits __log_limiter_get_limits(const char *tag, int prio);
+struct limiter_limits __log_limiter_get_limits(struct limiter_data *limiter_data, const char *tag, int prio);
 
-void __log_limiter_update(const struct log_config *config);
+void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config);
 
-int __log_limiter_dump_rule(struct rule **, char *, const size_t);
+int __log_limiter_dump_rule(struct limiter_data *limiter_data, struct rule **r, char *buf, const size_t size);
 
 // Note: result only valid until next __log_limiter_{update,destroy}
-list_head __log_limiter_get_pid_limits(void);
+list_head __log_limiter_get_pid_limits(struct limiter_data *limiter_data);
 
 #ifdef __cplusplus
 }
index c17471b..b8f217c 100644 (file)
@@ -67,7 +67,7 @@ static bool __setup_runtime_watch(char const *path)
        return true;
 }
 
-static void __apply_update(void)
+static void __apply_update(struct limiter_data *limiter_data)
 {
        assert(inotify_path);
 
@@ -83,7 +83,7 @@ static void __apply_update(void)
                const int l = pthread_rwlock_wrlock(&log_limiter_lock);
                assert(!l); // we should never have a read lock at this point so wrlock() cannot fail
 
-               __log_limiter_update(&config);
+               __log_limiter_update(limiter_data, &config);
                pthread_rwlock_unlock(&log_limiter_lock);
        }
 }
@@ -141,7 +141,7 @@ void __dynamic_config_destroy(void)
        inotify_fd = -1;
 }
 
-void __dynamic_config_update(void)
+void __dynamic_config_update(struct limiter_data *limiter_data)
 {
        if (inotify_fd < 0)
                return;
@@ -187,7 +187,7 @@ void __dynamic_config_update(void)
        if (lock_r < 0)
                return;
 
-       __apply_update();
+       __apply_update(limiter_data);
 
        pthread_mutex_unlock(&log_dynamic_config_lock);
 }
index 98488d6..9469e02 100644 (file)
@@ -73,6 +73,7 @@ extern void __dlog_init_pipe(const struct log_config *conf);
 extern void __dlog_init_android(const struct log_config *conf);
 
 bool limiter;
+struct limiter_data *limiter_data;
 static bool dynamic_config;
 static bool plog[LOG_ID_MAX];
 static bool plog_default_values[LOG_ID_MAX];
@@ -98,9 +99,10 @@ static void __configure_limiter(struct log_config *static_config, struct log_con
        if (!limiter)
                return;
 
-       limiter = __log_limiter_create(static_config);
-       if (limiter && dynamic_config)
-               __log_limiter_update(both_config);
+       limiter_data = __log_limiter_create(static_config);
+       if (limiter_data && dynamic_config)
+               __log_limiter_update(limiter_data, both_config);
+       limiter = (bool)limiter_data;
 }
 
 static int __configure_backend(struct log_config *config)
@@ -349,12 +351,12 @@ static int dlog_check_limiter(log_id_t log_id, int prio, const char *tag)
                return DLOG_ERROR_NOT_PERMITTED;
 
        if (dynamic_config)
-               __dynamic_config_update();
+               __dynamic_config_update(limiter_data);
 
        if (limiter) {
                struct pass_log_result should_log = { .decision = DECISION_DENIED };
                if (!pthread_rwlock_rdlock(&log_limiter_lock)) {
-                       should_log = __log_limiter_pass_log(tag, prio);
+                       should_log = __log_limiter_pass_log(limiter_data, tag, prio);
                        pthread_rwlock_unlock(&log_limiter_lock);
                }
 
@@ -750,7 +752,7 @@ void __dlog_fini(void)
        enable_secure_logs = true;
        enable_critical = false;
        __deduplicate_destroy();
-       __log_limiter_destroy();
+       __log_limiter_destroy(limiter_data);
        limiter = false;
        __dynamic_config_destroy();
 }
index 64a28af..c3a7c47 100644 (file)
@@ -586,24 +586,24 @@ static void get_pid_rule(void *prerule, void *prepid)
                printf("%zu logs/min\n", rule->limit);
 }
 
-static void get_pid_limits(const struct parsed_params *params, const char *config_path, struct log_config *conf)
+static void get_pid_limits(struct limiter_data *limiter_data, const struct parsed_params *params, const char *config_path, struct log_config *conf)
 {
        log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply
-       __log_limiter_update(conf);
+       __log_limiter_update(limiter_data, conf);
 
        pid_t pid_to_find = params->pid;
-       list_head pidrules = __log_limiter_get_pid_limits();
+       list_head pidrules = __log_limiter_get_pid_limits(limiter_data);
        if (pidrules)
                list_foreach(pidrules, &pid_to_find, get_pid_rule);
 }
 
-static void get_limits(const struct parsed_params *params, const char *config_path, struct log_config *conf)
+static void get_limits(struct limiter_data *limiter_data, const struct parsed_params *params, const char *config_path, struct log_config *conf)
 {
-       struct limiter_limits lims_static = __log_limiter_get_limits(params->tag, params->prio);
+       struct limiter_limits lims_static = __log_limiter_get_limits(limiter_data, params->tag, params->prio);
 
        log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply
-       __log_limiter_update(conf);
-       struct limiter_limits lims_dynamic = __log_limiter_get_limits(params->tag, params->prio);
+       __log_limiter_update(limiter_data, conf);
+       struct limiter_limits lims_dynamic = __log_limiter_get_limits(limiter_data, params->tag, params->prio);
 
        bool shadowed = false;
        if (strcmp(params->tag, "*")) {
@@ -657,20 +657,20 @@ static void print_limits_for_prio(const struct parsed_params *params, const char
        }
 }
 
-static void get_prio_limits(const struct parsed_params *params, const char *config_path, struct log_config *conf)
+static void get_prio_limits(struct limiter_data *limiter_data, const struct parsed_params *params, const char *config_path, struct log_config *conf)
 {
        static const char prio_list[] = {'V', 'D', 'I', 'W', 'E', 'F' , 'S' , '*'};
        struct prio_applies_to applies_dynamic = { .count = 0 };
        struct prio_applies_to applies_static = { .count = 0 };
 
        for (size_t i = 0; i < NELEMS(prio_list); i++)
-               applies_static.lims[i] = __log_limiter_get_limits(params->tag, prio_list[i]);
+               applies_static.lims[i] = __log_limiter_get_limits(limiter_data, params->tag, prio_list[i]);
 
        log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply
-       __log_limiter_update(conf);
+       __log_limiter_update(limiter_data, conf);
 
        for (size_t i = 0; i < NELEMS(prio_list); i++) {
-               applies_dynamic.lims[i] = __log_limiter_get_limits(params->tag, prio_list[i]);
+               applies_dynamic.lims[i] = __log_limiter_get_limits(limiter_data, params->tag, prio_list[i]);
                bool shadowed = false;
 
                print_limits_for_prio(params, prio_list, &applies_dynamic, i, &shadowed, true);
@@ -681,19 +681,20 @@ static void get_prio_limits(const struct parsed_params *params, const char *conf
 
 int handle_get(const struct parsed_params *params, const char *config_path, struct log_config *conf)
 {
-       if (!__log_limiter_create(conf)) {
+       struct limiter_data *limiter_data = __log_limiter_create(conf);
+       if (!limiter_data) {
                ERR("error creating limiter\n");
                return EXIT_FAILURE;
        }
 
        if (params->pid != 0)
-               get_pid_limits(params, config_path, conf);
+               get_pid_limits(limiter_data, params, config_path, conf);
        else if (params->prio == '\0')
-               get_prio_limits(params, config_path, conf);
+               get_prio_limits(limiter_data, params, config_path, conf);
        else
-               get_limits(params, config_path, conf);
+               get_limits(limiter_data, params, config_path, conf);
 
-       __log_limiter_destroy();
+       __log_limiter_destroy(limiter_data);
        return EXIT_SUCCESS;
 }
 
@@ -713,27 +714,28 @@ void dump_pid_rule(void *prerule, void *_garbage)
 int handle_dump(const struct parsed_params *params, const char *config_path, struct log_config *conf)
 {
        (void) params;
-       if (!__log_limiter_create(conf)) {
+       struct limiter_data *limiter_data = __log_limiter_create(conf);
+       if (!limiter_data) {
                ERR("error creating limiter\n");
                return EXIT_FAILURE;
        }
        char buf[1024];
 
        log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply
-       __log_limiter_update(conf);
+       __log_limiter_update(limiter_data, conf);
 
        struct rule *r = NULL;
        do {
-               int ret = __log_limiter_dump_rule(&r, buf, sizeof buf);
+               int ret = __log_limiter_dump_rule(limiter_data, &r, buf, sizeof buf);
                if (ret < 0) {
                        ERR("Error dumping rule\n");
-                       __log_limiter_destroy();
+                       __log_limiter_destroy(limiter_data);
                        return EXIT_FAILURE;
                }
                printf("%s\n", buf);
        } while (r);
 
-       list_head pidrules = __log_limiter_get_pid_limits();
+       list_head pidrules = __log_limiter_get_pid_limits(limiter_data);
        if (pidrules)
                list_foreach(pidrules, NULL, dump_pid_rule);
 
@@ -758,7 +760,7 @@ int handle_dump(const struct parsed_params *params, const char *config_path, str
                                ret != 0 ? "UNKNOWN" : stdout_enabled ? "ENABLED" : "DISABLED");
        }
 
-       __log_limiter_destroy();
+       __log_limiter_destroy(limiter_data);
        return EXIT_SUCCESS;
 }
 
index de9ce71..dd4832f 100644 (file)
 #include <qos_defaults.h>
 #include <hash.h>
 
-typedef int (*hash_cmp_func_t)(struct rule *, struct rule *);
-typedef int (*hash_match_func_t)(struct rule *, unsigned, const char *, int);
-
-struct hashmap {
-       hash_cmp_func_t cmp;
-       hash_match_func_t match;
-       int size;
-       void *bucket[];
-};
-
-static list_head pid_rules = NULL;
-
-static struct hashmap *rules_hashmap = NULL;
-
-/* Keep rules table as single-linked list */
-static struct rule *current_rules_table = NULL;
-static struct rule *original_rules_table = NULL;
-
 #define HASHMAP_MASK(hm)          ((int)(hm->size - 1))
 #define HASHMAP_LINEAR_PROBE_LEAP 1
 
-static struct pid_limit *cached_pid_rule = NULL;
 static struct pid_limit no_limit_rule = { .pid = -1, .limit = SIZE_MAX };
-static size_t sent_by_me = 0;
-static time_t last_pid_time = -1;
-static time_t refresh_rate_s = -1;
-static pid_t prev_pid = -1;
-static bool already_exceeded = false;
+
+struct find_my_rule_data {
+       pid_t my_pid;
+       struct limiter_data *limiter_data;
+};
 
 void find_my_rule(elem_value value, void *userdata)
 {
-       const pid_t my_pid = *(pid_t *)userdata;
+       struct find_my_rule_data *find_my_rule_data = userdata;
        struct pid_limit *const p = (struct pid_limit *) value;
 
-       if (p->pid == my_pid)
-               cached_pid_rule = p;
+       if (p->pid == find_my_rule_data->my_pid)
+               find_my_rule_data->limiter_data->cached_pid_rule = p;
 }
 
-static struct pass_log_result block_by_pid(void)
+static struct pass_log_result block_by_pid(struct limiter_data *limiter_data)
 {
+       assert(limiter_data);
+
        pid_t my_pid = getpid();
 
        /* We cache the rule relevant to our pid since
         * our pid doesn't usually change. Fork exists
         * though so we have to pay attention lest we
         * use an obsolete value. */
-       if (!cached_pid_rule || ((cached_pid_rule->pid != -1 || prev_pid != my_pid) && cached_pid_rule->pid != my_pid)) {
+       if (!limiter_data->cached_pid_rule || ((limiter_data->cached_pid_rule->pid != -1 || limiter_data->prev_pid != my_pid) && limiter_data->cached_pid_rule->pid != my_pid)) {
 
                /* Forking resets the counter (mostly so that launcher
                 * log usage does not get inherited by innocent apps,
                 * since forking is otherwise fairly rare as far as
                 * typical dlog clients go). */
-               if (prev_pid != my_pid) {
-                       last_pid_time = -1;
-                       already_exceeded = false;
-                       sent_by_me = 0;
+               if (limiter_data->prev_pid != my_pid) {
+                       limiter_data->last_pid_time = -1;
+                       limiter_data->already_exceeded = false;
+                       limiter_data->sent_by_me = 0;
                }
 
-               cached_pid_rule = &no_limit_rule;
-               list_foreach(pid_rules, &my_pid, find_my_rule);
+               limiter_data->cached_pid_rule = &no_limit_rule;
+               list_foreach(limiter_data->pid_rules, &(struct find_my_rule_data) {
+                       .my_pid = my_pid,
+                       .limiter_data = limiter_data,
+               }, find_my_rule);
        }
 
        const time_t now = time(NULL);
-       if (now >= last_pid_time + refresh_rate_s) {
-               last_pid_time = now;
-               already_exceeded = false;
-               sent_by_me = 1;
+       if (now >= limiter_data->last_pid_time + limiter_data->refresh_rate_s) {
+               limiter_data->last_pid_time = now;
+               limiter_data->already_exceeded = false;
+               limiter_data->sent_by_me = 1;
        } else
-               sent_by_me += 1;
+               limiter_data->sent_by_me += 1;
 
-       if (cached_pid_rule->limit > __LOG_LIMITER_LIMIT_MAX)
+       if (limiter_data->cached_pid_rule->limit > __LOG_LIMITER_LIMIT_MAX)
                return (struct pass_log_result) { .decision = DECISION_ALLOWED, };
 
-       prev_pid = my_pid;
-       if (sent_by_me <= cached_pid_rule->limit)
+       limiter_data->prev_pid = my_pid;
+       if (limiter_data->sent_by_me <= limiter_data->cached_pid_rule->limit)
                return (struct pass_log_result) { .decision = DECISION_ALLOWED, };
-       else if (!already_exceeded) {
-               already_exceeded = true;
+       else if (!limiter_data->already_exceeded) {
+               limiter_data->already_exceeded = true;
                return (struct pass_log_result) {
                        .decision = DECISION_PID_LIMIT_EXCEEDED_MESSAGE,
-                       .logs_per_period = cached_pid_rule->limit,
-                       .period_s = refresh_rate_s,
+                       .logs_per_period = limiter_data->cached_pid_rule->limit,
+                       .period_s = limiter_data->refresh_rate_s,
                };
        } else
                return (struct pass_log_result) { .decision = DECISION_DENIED, };
@@ -308,7 +294,7 @@ static struct rule *hashmap_search(struct hashmap *hm,
 }
 
 /* Must be always executed after __log_config_read() */
-int __log_limiter_initialize(struct rule *rules_table)
+int __log_limiter_initialize(struct limiter_data *limiter_data, struct rule *rules_table)
 {
        int hm_size;
        struct rule *rlist = NULL;
@@ -326,35 +312,40 @@ int __log_limiter_initialize(struct rule *rules_table)
        }
 
        /* Allocate hashmap */
-       rules_hashmap = (struct hashmap *) hashmap_create(hm_size,
+       limiter_data->rules_hashmap = (struct hashmap *) hashmap_create(hm_size,
                                                        &rule_compare,
                                                        &rule_match);
-       if (NULL == rules_hashmap || !rules_hashmap->size) {
-               hashmap_destroy(&rules_hashmap);
+       if (NULL == limiter_data->rules_hashmap || !limiter_data->rules_hashmap->size) {
+               hashmap_destroy(&limiter_data->rules_hashmap);
                return -1;
        }
 
        /* Add rule to hashmap */
        rlist = rules_table;
        while (rlist) {
-               hashmap_add(rules_hashmap, rlist);
+               hashmap_add(limiter_data->rules_hashmap, rlist);
                rlist = rlist->prev;
        }
 
        return 0;
 }
 
-static void destroy_hashmap_etc(void)
+static void destroy_hashmap_etc(struct limiter_data *limiter_data)
 {
-       hashmap_destroy(&rules_hashmap);
-       rules_destroy(&original_rules_table);
+       assert(limiter_data);
+
+       hashmap_destroy(&limiter_data->rules_hashmap);
+       rules_destroy(&limiter_data->original_rules_table);
 }
 
-void __log_limiter_destroy(void)
+void __log_limiter_destroy(struct limiter_data *limiter_data)
 {
-       cached_pid_rule = NULL;
-       list_clear_free_contents(&pid_rules);
-       destroy_hashmap_etc();
+       if (!limiter_data)
+               return;
+
+       list_clear_free_contents(&limiter_data->pid_rules);
+       destroy_hashmap_etc(limiter_data);
+       free(limiter_data);
 }
 
 struct rule *__log_limiter_add_rule(struct rule **rules_table, const char *tag, int prio, int limit)
@@ -394,16 +385,16 @@ struct rule *__log_limiter_add_rule(struct rule **rules_table, const char *tag,
        return r;
 }
 
-struct limiter_limits __log_limiter_get_limits(const char *tag, int prio)
+struct limiter_limits __log_limiter_get_limits(struct limiter_data *limiter_data, const char *tag, int prio)
 {
        const struct rule fallback = { .limit = -1 };
        const char prio_c = util_prio_to_char(prio);
 
        return (struct limiter_limits) {
-               .tag_and_prio = (hashmap_search(rules_hashmap, tag, prio_c) ?: &fallback)->limit,
-               .tag          = (hashmap_search(rules_hashmap, tag, '*')    ?: &fallback)->limit,
-               .prio         = (hashmap_search(rules_hashmap, "*", prio_c) ?: &fallback)->limit,
-               .global       = (hashmap_search(rules_hashmap, "*", '*')    ?: &fallback)->limit,
+               .tag_and_prio = (hashmap_search(limiter_data->rules_hashmap, tag, prio_c) ?: &fallback)->limit,
+               .tag          = (hashmap_search(limiter_data->rules_hashmap, tag, '*')    ?: &fallback)->limit,
+               .prio         = (hashmap_search(limiter_data->rules_hashmap, "*", prio_c) ?: &fallback)->limit,
+               .global       = (hashmap_search(limiter_data->rules_hashmap, "*", '*')    ?: &fallback)->limit,
        };
 }
 
@@ -414,13 +405,15 @@ struct limiter_limits __log_limiter_get_limits(const char *tag, int prio)
  * On first time being blocked, it will return *_LIMIT_EXCEEDED_MESSAGE in the decision field,
  * which allows the callee to write a relevant message to logs.
  */
-struct pass_log_result __log_limiter_pass_log(const char *tag, int prio)
+struct pass_log_result __log_limiter_pass_log(struct limiter_data *limiter_data, const char *tag, int prio)
 {
-       struct pass_log_result pid_result = block_by_pid();
+       assert(limiter_data);
+
+       struct pass_log_result pid_result = block_by_pid(limiter_data);
        if (pid_result.decision != DECISION_ALLOWED)
                return pid_result;
 
-       if (!rules_hashmap)
+       if (!limiter_data->rules_hashmap)
                return (struct pass_log_result) { .decision = DECISION_ALLOWED, };
 
        /* allow empty-tagged messages and make it easy to catch an application that does that */
@@ -429,10 +422,10 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio)
 
        const char prio_c = util_prio_to_char(prio);
        struct rule *r =
-               hashmap_search(rules_hashmap, tag, prio_c) ?:
-               hashmap_search(rules_hashmap, tag, '*')    ?:
-               hashmap_search(rules_hashmap, "*", prio_c) ?:
-               hashmap_search(rules_hashmap, "*", '*');
+               hashmap_search(limiter_data->rules_hashmap, tag, prio_c) ?:
+               hashmap_search(limiter_data->rules_hashmap, tag, '*')    ?:
+               hashmap_search(limiter_data->rules_hashmap, "*", prio_c) ?:
+               hashmap_search(limiter_data->rules_hashmap, "*", '*');
 
        if (!r)
                return (struct pass_log_result) { .decision = DECISION_ALLOWED, };
@@ -447,7 +440,7 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio)
        if (0 > now)
                return (struct pass_log_result) { .decision = DECISION_ALLOWED, };
 
-       if (now - r->start <= refresh_rate_s) {
+       if (now - r->start <= limiter_data->refresh_rate_s) {
                if (r->hit >= 0) {
                        if (r->hit < r->limit) {
                                r->hit++;
@@ -457,7 +450,7 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio)
                        return (struct pass_log_result) {
                                .decision = DECISION_TAG_LIMIT_EXCEEDED_MESSAGE,
                                .logs_per_period = r->limit,
-                               .period_s = refresh_rate_s,
+                               .period_s = limiter_data->refresh_rate_s,
                        };
                } else {
                        r->hit++;
@@ -470,6 +463,11 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio)
        }
 }
 
+struct iteration_data {
+       struct rule **rules_table;
+       struct limiter_data *limiter_data;
+};
+
 /**
  * @brief Limiter rule from config
  * @details Adds a limiter rule from a config entry, if one exists inside
@@ -481,8 +479,8 @@ static void regular_limiter_iteration(const char *key, const char *value, void *
 {
        assert(key);
        assert(value);
-       struct rule **rules_table = (struct rule **)userdata;
-       assert(rules_table);
+       assert(userdata);
+       struct iteration_data *data = userdata;
 
        static const int prefix_len = sizeof("limiter|") - 1;
        char * delimiter_pos;
@@ -505,11 +503,16 @@ static void regular_limiter_iteration(const char *key, const char *value, void *
        else
                limit = atoi(value);
 
-       __log_limiter_add_rule(rules_table, limiter_tag, *(delimiter_pos + 1), limit);
+       __log_limiter_add_rule(data->rules_table, limiter_tag, *(delimiter_pos + 1), limit);
 }
 
 static void pid_limiter_iteration(const char *key, const char *value, void *userdata)
 {
+       assert(key);
+       assert(value);
+       assert(userdata);
+       struct iteration_data *data = userdata;
+
        if (strncmp(key, "pidlimit|", sizeof "pidlimit|" - 1))
                return;
 
@@ -529,7 +532,7 @@ static void pid_limiter_iteration(const char *key, const char *value, void *user
        p->limit = limit;
        p->pid = pid;
 
-       list_add(&pid_rules, p);
+       list_add(&data->limiter_data->pid_rules, p);
 }
 
 static void __config_iteration(const char *key, const char *value, void *userdata)
@@ -538,24 +541,41 @@ static void __config_iteration(const char *key, const char *value, void *userdat
        pid_limiter_iteration(key, value, userdata);
 }
 
-int __log_limiter_create(const struct log_config *config)
+struct limiter_data *__log_limiter_create(const struct log_config *config)
 {
        assert(config);
-       assert(!original_rules_table);
-       assert(!rules_hashmap);
 
-       last_pid_time = time(NULL);
-       cached_pid_rule = NULL;
-       log_config_foreach(config, __config_iteration, &original_rules_table);
-       refresh_rate_s = log_config_get_int(config, "qos_refresh_rate_s", DEFAULT_QOS_LIMIT_DURATION_S);
+       struct limiter_data *ret = calloc(1, sizeof(struct limiter_data));
+       if (!ret)
+               return NULL;
 
-       const int r = __log_limiter_initialize(original_rules_table);
+       ret->original_rules_table = NULL;
+       ret->current_rules_table = NULL;
+       ret->prev_pid = -1;
+       ret->sent_by_me = 0;
+       ret->already_exceeded = false;
+       ret->last_pid_time = time(NULL);
+       ret->cached_pid_rule = NULL;
+       ret->pid_rules = NULL;
+       log_config_foreach(config, __config_iteration, &(struct iteration_data) {
+               .rules_table = &ret->original_rules_table,
+               .limiter_data = ret,
+       });
+       ret->refresh_rate_s = log_config_get_int(config, "qos_refresh_rate_s", DEFAULT_QOS_LIMIT_DURATION_S);
+       ret->rules_hashmap = NULL;
+
+       const int r = __log_limiter_initialize(ret, ret->original_rules_table);
        if (r) {
-               rules_destroy(&original_rules_table);
-               return pid_rules != NULL;
+               rules_destroy(&ret->original_rules_table);
+               if (ret->pid_rules != NULL)
+                       return ret;
+               else {
+                       free(ret);
+                       return NULL;
+               }
        }
 
-       for (struct rule *i = original_rules_table; i; i = i->prev)
+       for (struct rule *i = ret->original_rules_table; i; i = i->prev)
                i->type = RULE_STATIC;
 
        /* The following makes sure that the current ruleset is initialized.
@@ -563,32 +583,36 @@ int __log_limiter_create(const struct log_config *config)
         * at this point. In general, whoever calls this function also calls
         * __log_limiter_update, so this shouldn't be needed. However, it's
         * a good idea to do this, and also this was needed for some tests. */
-       __log_limiter_update(&(struct log_config) { });
+       __log_limiter_update(ret, &(struct log_config) { });
 
-       return 1;
+       return ret;
 }
 
-void __log_limiter_update(const struct log_config *config)
+void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config)
 {
        assert(config);
-       assert(!original_rules_table || rules_hashmap);
+       assert(!limiter_data->original_rules_table || limiter_data->rules_hashmap);
+       assert(limiter_data);
 
        struct rule *rules_table = NULL;
-       for (struct rule *i = original_rules_table; i; i = i->prev) {
+       for (struct rule *i = limiter_data->original_rules_table; i; i = i->prev) {
                struct rule *r = __log_limiter_add_rule(&rules_table, i->tag, i->prio, i->limit);
                if (!r)
                        continue;
                r->type = RULE_STATIC;
        }
 
-       cached_pid_rule = NULL;
-       list_clear_free_contents(&pid_rules);
-       log_config_foreach(config, __config_iteration, &rules_table);
+       limiter_data->cached_pid_rule = NULL;
+       list_clear_free_contents(&limiter_data->pid_rules);
+       log_config_foreach(config, __config_iteration, &(struct iteration_data) {
+               .rules_table = &rules_table,
+               .limiter_data = limiter_data,
+       });
 
-       if (rules_hashmap) {
+       if (limiter_data->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);
+                       const struct rule *const prev_rule = hashmap_search(limiter_data->rules_hashmap, i->tag, prio_c);
                        if (!prev_rule)
                                continue;
 
@@ -597,14 +621,14 @@ void __log_limiter_update(const struct log_config *config)
                }
        }
 
-       hashmap_destroy(&rules_hashmap);
-       if (__log_limiter_initialize(rules_table) < 0) {
-               destroy_hashmap_etc();
+       hashmap_destroy(&limiter_data->rules_hashmap);
+       if (__log_limiter_initialize(limiter_data, rules_table) < 0) {
+               destroy_hashmap_etc(limiter_data);
                return;
        }
 
-       rules_destroy(&current_rules_table);
-       current_rules_table = rules_table;
+       rules_destroy(&limiter_data->current_rules_table);
+       limiter_data->current_rules_table = rules_table;
 }
 
 /**
@@ -615,9 +639,9 @@ void __log_limiter_update(const struct log_config *config)
  * @param[in] size The size of the buffer
  * @returns 0 on success, -1 on failure
  */
-int __log_limiter_dump_rule(struct rule **r, char *buf, const size_t size)
+int __log_limiter_dump_rule(struct limiter_data *limiter_data, struct rule **r, char *buf, const size_t size)
 {
-       struct rule *ruleptr = *r ? : current_rules_table;
+       struct rule *ruleptr = *r ? : limiter_data->current_rules_table;
        int s = 0;
 
        if (!ruleptr) {
@@ -646,7 +670,7 @@ int __log_limiter_dump_rule(struct rule **r, char *buf, const size_t size)
        return 0;
 }
 
-list_head __log_limiter_get_pid_limits(void)
+list_head __log_limiter_get_pid_limits(struct limiter_data *limiter_data)
 {
-       return pid_rules;
+       return limiter_data->pid_rules;
 }
index 4c84526..524d928 100644 (file)
@@ -14,6 +14,7 @@
 
 // DLog
 #include <dynamic_config.h>
+#include <loglimiter-internal.h>
 
 pthread_rwlock_t log_limiter_lock = PTHREAD_RWLOCK_INITIALIZER;
 bool limiter;
@@ -95,8 +96,9 @@ void __update_plog(const struct log_config *conf)
 }
 
 static bool limiter_update_called = false;
-void __log_limiter_update(struct log_config *config)
+void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config)
 {
+       assert(limiter_data == (struct limiter_data *)0x12345);
        limiter_update_called = true;
 }
 
@@ -128,9 +130,9 @@ int __wrap_pthread_mutex_trylock(pthread_mutex_t *mutex)
 int main(void)
 {
        // check whether these blow up when called before init
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
        __dynamic_config_destroy();
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
 
        struct log_config conf = {NULL, NULL};
        assert(!__dynamic_config_create(&conf));
@@ -156,32 +158,32 @@ int main(void)
        assert(!critical_failure_detected);
 
        limiter = false;
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
        assert(update_plog_called);
        assert(!limiter_update_called);
        update_plog_called = false;
 
        limiter = true;
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
        assert(update_plog_called);
        assert(limiter_update_called);
        update_plog_called = false;
        limiter_update_called = false;
 
        fail_read = true;
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
        assert(!update_plog_called);
        assert(!limiter_update_called);
        fail_read = false;
 
        empty_read = true;
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
        assert(!update_plog_called);
        assert(!limiter_update_called);
        empty_read = false;
 
        pretend_the_mutex_is_locked = true;
-       __dynamic_config_update();
+       __dynamic_config_update((struct limiter_data *)0x12345);
        assert(!update_plog_called);
        assert(!limiter_update_called);
        pretend_the_mutex_is_locked = false;
index 8978656..f9c8954 100644 (file)
 #include <libdlog.h>
 #include <logconfig.h>
 #include <loglimiter.h>
+#include <loglimiter-internal.h>
 
-void __log_limiter_update(const struct log_config *config) { }
-void __log_limiter_destroy(void) { }
+void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config) { }
+void __log_limiter_destroy(struct limiter_data *limiter_data) { }
 void __dynamic_config_destroy(void) { }
 
 static bool destroyed;
@@ -62,20 +63,21 @@ int __wrap_log_config_read(struct log_config *config)
 }
 
 struct pass_log_result limiter_ret;
-struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) { return limiter_ret; }
+struct pass_log_result __log_limiter_pass_log(struct limiter_data *limiter_data, const char *tag, int prio) { return limiter_ret; }
 
 static bool limiter_created;
-int __log_limiter_create(const struct log_config *config)
+static struct limiter_data limiter_data_ret;
+struct limiter_data *__log_limiter_create(const struct log_config *config)
 {
        limiter_created = true;
-       return 1;
+       return &limiter_data_ret;
 }
 
 static bool use_dynamic_conf;
 bool __dynamic_config_create(struct log_config *config) { return use_dynamic_conf; }
 
 static bool dynamic_config_called;
-void __dynamic_config_update(void) { dynamic_config_called = true; }
+void __dynamic_config_update(struct limiter_data *limiter_data) { dynamic_config_called = true; }
 
 bool fail_snprintf;
 int __wrap_snprintf(char *str, size_t size, const char *format, ...)
index e564943..f5672bc 100644 (file)
@@ -23,6 +23,7 @@
 #include <libdlog.h>
 #include <logconfig.h>
 #include <loglimiter.h>
+#include <loglimiter-internal.h>
 
 int wtl(log_id_t buf_id, log_priority pri, const char *tag, const char *msg, struct timespec *tp_mono) { return 0xABCD; }
 void __dlog_init_pipe(const struct log_config *conf) { write_to_log = wtl; }
@@ -36,13 +37,14 @@ int __wrap_log_config_read(struct log_config *config)
 }
 
 // lobotomize various mechanisms I don't want to deal with
-void __log_limiter_update(const struct log_config *config) { }
-void __log_limiter_destroy(void) { }
+void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config) { }
+void __log_limiter_destroy(struct limiter_data *limiter_data) { }
 void __dynamic_config_destroy(void) { }
-struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) { return (struct pass_log_result) { .decision = DECISION_ALLOWED }; }
-int __log_limiter_create(const struct log_config *config) { return 1; }
+struct pass_log_result __log_limiter_pass_log(struct limiter_data *data, const char *tag, int prio) { return (struct pass_log_result) { .decision = DECISION_ALLOWED }; }
+static struct limiter_data limiter_data_ret;
+struct limiter_data *__log_limiter_create(const struct log_config *config) { return &limiter_data_ret; }
 bool __dynamic_config_create(struct log_config *config) { return false; }
-void __dynamic_config_update(void) { }
+void __dynamic_config_update(struct limiter_data *limiter_data) { }
 void __dlog_init_android(const struct log_config *conf) { }
 
 
index 8edeb71..8de59ec 100644 (file)
 
 int main(void)
 {
-       __log_limiter_destroy(); // check whether it explodes if called before init
+       __log_limiter_destroy(NULL); // check whether it explodes if called before init
 
        struct log_config conf = {NULL, NULL};
        assert(!__log_limiter_create(&conf));
 
+       /* TODO
        struct rule *r = NULL;
        char buffer[10];
        assert(!__log_limiter_dump_rule(&r, buffer, sizeof buffer));
        assert(r == NULL);
+       */
 
        log_config_set(&conf, "limiter|*|*"  , "allow");
        log_config_set(&conf, "limiter|FOO|*", "deny");
        log_config_set(&conf, "limiter|*|E"  , "deny");
        log_config_set(&conf, "limiter|FOO|E", "7");
-       assert(__log_limiter_create(&conf));
+       struct limiter_data *limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
 
        fail_malloc = 1;
-       __log_limiter_update(&conf);
+       __log_limiter_update(limiter_data, &conf);
        for (int i = 0; i < 100; ++i) {
-               assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_ALLOWED);
-               assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED);
-               assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "FOO", 'F').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "BAR", 'F').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "BAR", 'E').decision == DECISION_ALLOWED);
        }
 
        fail_malloc = 2;
-       __log_limiter_update(&conf);
+       __log_limiter_update(limiter_data, &conf);
        for (int i = 0; i < 100; ++i) {
-               assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_ALLOWED);
-               assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED);
-               assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "FOO", 'F').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "BAR", 'F').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "BAR", 'E').decision == DECISION_ALLOWED);
        }
 
        fail_malloc = 0;
-       __log_limiter_destroy();
-       assert(__log_limiter_create(&conf));
+       __log_limiter_destroy(limiter_data);
+       limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
 
        fail_time = true;
-       assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
+       assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED);
        fail_time = false;
 
-       int rule_count = get_rulecount();
+       int rule_count = get_rulecount(limiter_data);
        log_config_set(&conf, "irrelevant", "entry");
-       assert(rule_count == get_rulecount());
-       __log_limiter_update(&conf);
+       assert(rule_count == get_rulecount(limiter_data));
+       __log_limiter_update(limiter_data, &conf);
 
        for (int i = 1; i <= 2; ++i) {
                struct rule *r = NULL;
                char buf[128];
                fail_snprintf = i;
-               assert(__log_limiter_dump_rule(&r, buf, sizeof buf) == -1);
+               assert(__log_limiter_dump_rule(limiter_data, &r, buf, sizeof buf) == -1);
        }
        fail_snprintf = 0;
 
index 9b616a2..a427c38 100644 (file)
@@ -25,66 +25,68 @@ int main(void)
        log_config_set(&conf, "limiter|FOO|*", "deny");
        log_config_set(&conf, "limiter|*|E"  , "deny");
        log_config_set(&conf, "limiter|FOO|E", "7");
-       assert(__log_limiter_create(&conf));
-       __log_limiter_update(&conf);
+       struct limiter_data *limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
+       __log_limiter_update(limiter_data, &conf);
 
        for (int i = 0; i < 100; ++i) {
-               assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_DENIED);
-               assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED);
-               assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_DENIED);
+               assert(__log_limiter_pass_log(limiter_data, "FOO", 'F').decision == DECISION_DENIED);
+               assert(__log_limiter_pass_log(limiter_data, "BAR", 'F').decision == DECISION_ALLOWED);
+               assert(__log_limiter_pass_log(limiter_data, "BAR", 'E').decision == DECISION_DENIED);
        }
 
-       __log_limiter_destroy();
-       assert(__log_limiter_create(&conf));
+       __log_limiter_destroy(limiter_data);
+       limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
 
        for (int i = 0; i < 7; ++i)
-               assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
-       assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_TAG_LIMIT_EXCEEDED_MESSAGE);
+               assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED);
+       assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_TAG_LIMIT_EXCEEDED_MESSAGE);
        for (int i = 0; i < 2; ++i)
-               assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_DENIED);
+               assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_DENIED);
 
        fail_time = false;
-       assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_DENIED);
+       assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_DENIED);
        future_time = true;
-       assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
+       assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED);
        future_time = false;
-       assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
+       assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED);
 
-       int rulecount = get_rulecount();
+       int rulecount = get_rulecount(limiter_data);
        assert(rulecount == 4);
 
-       const struct limiter_limits limits = __log_limiter_get_limits("FOO", 'E');
+       const struct limiter_limits limits = __log_limiter_get_limits(limiter_data, "FOO", 'E');
        assert(limits.tag_and_prio == 7);
        assert(limits.tag          == 0);
        assert(limits.prio         == 0);
        assert(limits.global       == __LOG_LIMITER_LIMIT_MAX + 1);
 
-       const struct limiter_limits lim_lowercase = __log_limiter_get_limits("FOO", 'e');
-       const struct limiter_limits lim_enum      = __log_limiter_get_limits("FOO", DLOG_ERROR);
-       const struct limiter_limits lim_numerical = __log_limiter_get_limits("FOO", '6');
+       const struct limiter_limits lim_lowercase = __log_limiter_get_limits(limiter_data, "FOO", 'e');
+       const struct limiter_limits lim_enum      = __log_limiter_get_limits(limiter_data, "FOO", DLOG_ERROR);
+       const struct limiter_limits lim_numerical = __log_limiter_get_limits(limiter_data, "FOO", '6');
        assert(!memcmp(&limits, &lim_lowercase, sizeof limits));
        assert(!memcmp(&limits, &lim_enum     , sizeof limits));
        assert(!memcmp(&limits, &lim_numerical, sizeof limits));
 
        log_config_set(&conf, "limiter|FOO|E", "12");
-       __log_limiter_update(&conf);
+       __log_limiter_update(limiter_data, &conf);
 
-       const struct limiter_limits limits_updated = __log_limiter_get_limits("FOO", 'E');
+       const struct limiter_limits limits_updated = __log_limiter_get_limits(limiter_data, "FOO", 'E');
        assert(limits_updated.tag_and_prio == 12);
-       assert(get_rulecount() == rulecount);
+       assert(get_rulecount(limiter_data) == rulecount);
 
        log_config_set(&conf, "limiter", "1");
        log_config_set(&conf, "limiter||E", "2");
        log_config_set(&conf, "limiter|QUUX|", "3");
        log_config_set(&conf, "limiter|", "4");
        log_config_set(&conf, "limiter||", "5");
-       __log_limiter_update(&conf);
-       assert(get_rulecount() == rulecount);
+       __log_limiter_update(limiter_data, &conf);
+       assert(get_rulecount(limiter_data) == rulecount);
 
        log_config_set(&conf, "limiter|ABC|?", "13");
-       __log_limiter_update(&conf);
+       __log_limiter_update(limiter_data, &conf);
 
-       const struct limiter_limits lim_unknown = __log_limiter_get_limits("ABC", DLOG_UNKNOWN);
+       const struct limiter_limits lim_unknown = __log_limiter_get_limits(limiter_data, "ABC", DLOG_UNKNOWN);
        assert(lim_unknown.tag_and_prio == 13);
 
        // bulk tests to test hashing and buckets
@@ -100,12 +102,12 @@ int main(void)
        S(BAC);
        S(ACB);
 #undef S
-       __log_limiter_update(&conf);
+       __log_limiter_update(limiter_data, &conf);
 
 #define A(T) \
-       assert(__log_limiter_get_limits(#T, 'D').tag_and_prio == 73); \
-       assert(__log_limiter_get_limits(#T, 'E').tag_and_prio == 74); \
-       assert(__log_limiter_get_limits(#T, 'F').tag_and_prio == 75)
+       assert(__log_limiter_get_limits(limiter_data, #T, 'D').tag_and_prio == 73); \
+       assert(__log_limiter_get_limits(limiter_data, #T, 'E').tag_and_prio == 74); \
+       assert(__log_limiter_get_limits(limiter_data, #T, 'F').tag_and_prio == 75)
 
        A(ABC);
        A(BCA);
@@ -128,10 +130,12 @@ int main(void)
                .tag = "QWE",
                .limit = 0,
        };
-       __log_limiter_destroy();
-       __log_limiter_initialize(&r1);
+       __log_limiter_destroy(limiter_data);
+       limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
+       __log_limiter_initialize(limiter_data, &r1);
 
-       assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
+       assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED);
 
        /* Searching a hashmap kinda doesn't work if you
         * fake hashes (esp. identical ones) so this just
@@ -151,8 +155,10 @@ int main(void)
                .limit = 0,
        };
 
-       __log_limiter_destroy();
-       __log_limiter_initialize(&r3);
+       __log_limiter_destroy(limiter_data);
+       limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
+       __log_limiter_initialize(limiter_data, &r3);
 
        struct rule r5 = {
                .prev = &r4,
@@ -168,8 +174,10 @@ int main(void)
                .limit = 0,
        };
 
-       __log_limiter_destroy();
-       __log_limiter_initialize(&r6);
+       __log_limiter_destroy(limiter_data);
+       limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
+       __log_limiter_initialize(limiter_data, &r6);
 
        // empty tag never gets blocked
        struct rule block_all = {
@@ -178,11 +186,13 @@ int main(void)
                .tag = "*",
                .limit = 0,
        };
-       __log_limiter_destroy();
-       __log_limiter_initialize(&block_all);
-       assert(__log_limiter_pass_log("tag", 'W').decision == DECISION_DENIED);
-       assert(__log_limiter_pass_log("", 'W').decision == DECISION_ALLOWED);
+       __log_limiter_destroy(limiter_data);
+       limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
+       __log_limiter_initialize(limiter_data, &block_all);
+       assert(__log_limiter_pass_log(limiter_data, "tag", 'W').decision == DECISION_DENIED);
+       assert(__log_limiter_pass_log(limiter_data, "", 'W').decision == DECISION_ALLOWED);
 
        log_config_free(&conf);
-       __log_limiter_destroy();
+       __log_limiter_destroy(limiter_data);
 }
index 45f71b7..6dbd6ee 100644 (file)
 #include <loglimiter.h>
 #include <loglimiter-internal.h>
 
-static size_t get_rulecount(void)
+static size_t get_rulecount(struct limiter_data *limiter_data)
 {
        size_t cnt = 0;
        struct rule *r = NULL;
        do {
                char buf[128];
-               assert(!__log_limiter_dump_rule(&r, buf, sizeof buf));
+               assert(!__log_limiter_dump_rule(limiter_data, &r, buf, sizeof buf));
                ++cnt;
        } while (r);
        return cnt;
index b258c65..9a96339 100644 (file)
@@ -32,18 +32,19 @@ int main(void)
        log_config_set(&conf, "pidlimit|77", "7");
        log_config_set(&conf, "pidlimit|88", "0");
        log_config_set(&conf, "pidlimit|55", "125");
-       assert(__log_limiter_create(&conf));
-       __log_limiter_update(&conf);
+       struct limiter_data *limiter_data = __log_limiter_create(&conf);
+       assert(limiter_data);
+       __log_limiter_update(limiter_data, &conf);
 
-#define PASS  assert(__log_limiter_pass_log("FOO", 'W').decision == DECISION_ALLOWED)
-#define MSG   assert(__log_limiter_pass_log("FOO", 'W').decision == DECISION_PID_LIMIT_EXCEEDED_MESSAGE)
-#define BLOCK assert(__log_limiter_pass_log("FOO", 'W').decision == DECISION_DENIED)
+#define PASS  assert(__log_limiter_pass_log(limiter_data, "FOO", 'W').decision == DECISION_ALLOWED)
+#define MSG   assert(__log_limiter_pass_log(limiter_data, "FOO", 'W').decision == DECISION_PID_LIMIT_EXCEEDED_MESSAGE)
+#define BLOCK assert(__log_limiter_pass_log(limiter_data, "FOO", 'W').decision == DECISION_DENIED)
 
        pid_ret = 77;
        for (int i =   0; i <   7; ++i) PASS;
        for (int i =   7; i <   8; ++i) MSG;
        for (int i =   8; i < 100; ++i) BLOCK;
-       __log_limiter_update(&conf); // shouldn't have any effect
+       __log_limiter_update(limiter_data, &conf); // shouldn't have any effect
        for (int i = 100; i < 200; ++i) BLOCK;
 
        advance_clock();
@@ -63,7 +64,7 @@ int main(void)
        for (int i = 126; i < 333; ++i) BLOCK;
 
        log_config_remove(&conf, "pidlimit|55");
-       __log_limiter_update(&conf);
+       __log_limiter_update(limiter_data, &conf);
        advance_clock();
 
        for (int i = 0; i < 1936; ++i) PASS;
@@ -76,5 +77,5 @@ int main(void)
 #undef BLOCK
 #undef PASS
 
-       __log_limiter_destroy();
+       __log_limiter_destroy(limiter_data);
 }