From 965868783e21e37f2eef83ec0c1bd02c3e49fcb3 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Thu, 6 Apr 2017 16:17:58 +0200 Subject: Implement on-the-fly reloading of lists. --- src/database.c | 1 - src/lists.c | 36 ++++++++++++++++++++++++++++++++++-- src/main.c | 8 +++++++- src/shared.h | 1 + 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/database.c b/src/database.c index c42cfb6..996a2c5 100644 --- a/src/database.c +++ b/src/database.c @@ -91,4 +91,3 @@ void db_destroy(void) pthread_mutex_unlock(&database_mutex); } - diff --git a/src/lists.c b/src/lists.c index 00e29ba..98ba866 100644 --- a/src/lists.c +++ b/src/lists.c @@ -33,6 +33,7 @@ typedef struct { } entry_t; static entry_t *entry_list; +static pthread_mutex_t entry_list_mutex = PTHREAD_MUTEX_INITIALIZER; static size_t total_entries; static int parse_entry(lexer_state_t *lexer, vstr_t *token, entry_type_t type) @@ -75,7 +76,8 @@ static int parse_entry(lexer_state_t *lexer, vstr_t *token, entry_type_t type) return 0; } -// FIXME: Make this MT-safe (lock the list before adding shit to it) +// NOTE: This function is not MT-safe. It's to be called only once during +// initialization. Use lists_reload to reload the lists on-the-fly. int lists_load(const char *file, size_t depth) { int error = 1, rv; @@ -127,7 +129,33 @@ out: void lists_destroy(void) { - // TODO... + entry_t *entry, *next; + + for (entry = entry_list; entry; entry = next){ + next = entry->list.next; + + free(entry->pattern); + free(entry); + } + + entry_list = NULL; + total_entries = 0; +} + +int lists_reload(const char *file) +{ + int ret; + + pthread_mutex_lock(&entry_list_mutex); + lists_destroy(); + ret = lists_load(file, 0); + if (!ret) + lists_destroy(); + pthread_mutex_unlock(&entry_list_mutex); + + // FIXME: invalidate all cached results + + return ret; } int lists_test(const char *revdns, const char *whois) @@ -135,6 +163,8 @@ int lists_test(const char *revdns, const char *whois) entry_t *entry; int total = 0; + pthread_mutex_lock(&entry_list_mutex); + eli_for(entry, entry_list, list) { // TODO: regexps if (entry->type == ENTRY_REVDNS && @@ -149,5 +179,7 @@ int lists_test(const char *revdns, const char *whois) total += entry->niceness; } + pthread_mutex_unlock(&entry_list_mutex); + return total; } diff --git a/src/main.c b/src/main.c index e5d5d6a..c10ec68 100644 --- a/src/main.c +++ b/src/main.c @@ -148,7 +148,13 @@ int handle_signals(void) if (signals_reload) { signals_reload = false; - DEBUG("reload the lists (not yet implemented)\n"); + eprintf("reloading the lists...\n"); + + // Don't initiate an exit if the lists failed to reload. + // It's better to continue operating with empty lists instead + // having to be restarted (with an empty revDNS/WHOIS cache). + if (lists_reload("schachts.list")) + eprintf("error: couldn't reload the lists\n"); } return 0; diff --git a/src/shared.h b/src/shared.h index 77c9d3f..13fd791 100644 --- a/src/shared.h +++ b/src/shared.h @@ -158,5 +158,6 @@ void lexer_perror_eg(lexer_state_t *ls, const char *expected); // lists.c int lists_load(const char *file, size_t depth); +int lists_reload(const char *file); void lists_destroy(void); int lists_test(const char *revdns, const char *whois); -- cgit