@cryptotaxi247 / netdata-1 / commits / cec38dd7d

Improve dyncfg exit (#15824)

Timotej S committed Aug 17, 2023 at 10:21 UTC cec38dd7de6a068b2bfc06712e766e111982d604
3 files changed +85 -45
daemon/static_threads.h
-33
@@ -5,39 +5,6 @@
5
6 #include "common.h"
7
8 -struct netdata_static_thread {
9 - // the name of the thread as it should appear in the logs
10 - char *name;
11 -
12 - // the section of netdata.conf to check if this is enabled or not
13 - char *config_section;
14 -
15 - // the name of the config option to check if it is true or false
16 - char *config_name;
17 -
18 - // the current status of the thread
19 - volatile sig_atomic_t enabled;
20 -
21 - // internal use, to maintain a pointer to the created thread
22 - netdata_thread_t *thread;
23 -
24 - // an initialization function to run before spawning the thread
25 - void (*init_routine) (void);
26 -
27 - // the threaded worker
28 - void *(*start_routine) (void *);
29 -
30 - // the environment variable to create
31 - char *env_name;
32 -
33 - // global variable
34 - bool *global_variable;
35 -};
36 -
37 -#define NETDATA_MAIN_THREAD_RUNNING CONFIG_BOOLEAN_YES
38 -#define NETDATA_MAIN_THREAD_EXITING (CONFIG_BOOLEAN_YES + 1)
39 -#define NETDATA_MAIN_THREAD_EXITED CONFIG_BOOLEAN_NO
40 -
8 extern const struct netdata_static_thread static_threads_common[];
9 extern const struct netdata_static_thread static_threads_linux[];
10 extern const struct netdata_static_thread static_threads_freebsd[];
libnetdata/dyn_conf/dyn_conf.c
+52 -12
@@ -20,10 +20,19 @@ struct deferred_cfg_send {
20 struct deferred_cfg_send *next;
21 };
22
23 +bool dyncfg_shutdown = false;
24 struct deferred_cfg_send *deferred_configs = NULL;
25 pthread_mutex_t deferred_configs_lock = PTHREAD_MUTEX_INITIALIZER;
26 pthread_cond_t deferred_configs_cond = PTHREAD_COND_INITIALIZER;
27
28 +static void deferred_config_free(struct deferred_cfg_send *dcs)
29 +{
30 + freez(dcs->plugin_name);
31 + freez(dcs->module_name);
32 + freez(dcs->job_name);
33 + freez(dcs);
34 +}
35 +
36 static void deferred_config_push_back(const char *plugin_name, const char *module_name, const char *job_name)
37 {
38 struct deferred_cfg_send *deferred = callocz(1, sizeof(struct deferred_cfg_send));
@@ -34,6 +43,11 @@ static void deferred_config_push_back(const char *plugin_name, const char *modul
43 deferred->job_name = strdupz(job_name);
44 }
45 pthread_mutex_lock(&deferred_configs_lock);
46 + if (dyncfg_shutdown) {
47 + pthread_mutex_unlock(&deferred_configs_lock);
48 + deferred_config_free(deferred);
49 + return;
50 + }
51 struct deferred_cfg_send *last = deferred_configs;
52 if (last == NULL)
53 deferred_configs = deferred;
@@ -46,25 +60,29 @@ static void deferred_config_push_back(const char *plugin_name, const char *modul
60 pthread_mutex_unlock(&deferred_configs_lock);
61 }
62
49 -static struct deferred_cfg_send *deferred_config_pop()
63 +static void deferred_configs_unlock()
64 +{
65 + dyncfg_shutdown = true;
66 + // if we get cancelled in pthread_cond_wait
67 + // we will arrive at cancelled cleanup handler
68 + // with mutex locked we need to unlock it
69 + pthread_mutex_unlock(&deferred_configs_lock);
70 +}
71 +
72 +static struct deferred_cfg_send *deferred_config_pop(void *ptr)
73 {
74 pthread_mutex_lock(&deferred_configs_lock);
52 - while (deferred_configs == NULL)
75 + while (deferred_configs == NULL) {
76 + netdata_thread_cleanup_push(deferred_configs_unlock, ptr);
77 pthread_cond_wait(&deferred_configs_cond, &deferred_configs_lock);
78 + netdata_thread_cleanup_pop(0);
79 + }
80 struct deferred_cfg_send *deferred = deferred_configs;
81 deferred_configs = deferred_configs->next;
82 pthread_mutex_unlock(&deferred_configs_lock);
83 return deferred;
84 }
85
60 -static void deferred_config_free(struct deferred_cfg_send *dcs)
61 -{
62 - freez(dcs->plugin_name);
63 - freez(dcs->module_name);
64 - freez(dcs->job_name);
65 - freez(dcs);
66 -}
67 -
86 static int _get_list_of_plugins_json_cb(const DICTIONARY_ITEM *item, void *entry, void *data)
87 {
88 UNUSED(item);
@@ -874,10 +892,30 @@ int dyn_conf_init(void)
892 return 0;
893 }
894
877 -void *dyncfg_main(void *in)
895 +static void dyncfg_cleanup(void *ptr) {
896 + struct netdata_static_thread *static_thread = (struct netdata_static_thread *) ptr;
897 + static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
898 +
899 + netdata_log_info("cleaning up...");
900 +
901 + pthread_mutex_lock(&deferred_configs_lock);
902 + dyncfg_shutdown = true;
903 + while (deferred_configs != NULL) {
904 + struct deferred_cfg_send *dcs = deferred_configs;
905 + deferred_configs = dcs->next;
906 + deferred_config_free(dcs);
907 + }
908 + pthread_mutex_unlock(&deferred_configs_lock);
909 +
910 + static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
911 +}
912 +
913 +void *dyncfg_main(void *ptr)
914 {
915 + netdata_thread_cleanup_push(dyncfg_cleanup, ptr);
916 +
917 while (!netdata_exit) {
880 - struct deferred_cfg_send *dcs = deferred_config_pop();
918 + struct deferred_cfg_send *dcs = deferred_config_pop(ptr);
919 const DICTIONARY_ITEM *plugin_item = dictionary_get_and_acquire_item(plugins_dict, dcs->plugin_name);
920 if (plugin_item == NULL) {
921 error_report("DYNCFG, plugin %s not found", dcs->plugin_name);
@@ -909,5 +947,7 @@ void *dyncfg_main(void *in)
947 deferred_config_free(dcs);
948 dictionary_acquired_item_release(plugins_dict, plugin_item);
949 }
950 +
951 + netdata_thread_cleanup_pop(1);
952 return NULL;
953 }
libnetdata/threads/threads.h
+33
@@ -20,6 +20,39 @@ typedef enum {
20
21 typedef pthread_t netdata_thread_t;
22
23 +struct netdata_static_thread {
24 + // the name of the thread as it should appear in the logs
25 + char *name;
26 +
27 + // the section of netdata.conf to check if this is enabled or not
28 + char *config_section;
29 +
30 + // the name of the config option to check if it is true or false
31 + char *config_name;
32 +
33 + // the current status of the thread
34 + volatile sig_atomic_t enabled;
35 +
36 + // internal use, to maintain a pointer to the created thread
37 + netdata_thread_t *thread;
38 +
39 + // an initialization function to run before spawning the thread
40 + void (*init_routine) (void);
41 +
42 + // the threaded worker
43 + void *(*start_routine) (void *);
44 +
45 + // the environment variable to create
46 + char *env_name;
47 +
48 + // global variable
49 + bool *global_variable;
50 +};
51 +
52 +#define NETDATA_MAIN_THREAD_RUNNING CONFIG_BOOLEAN_YES
53 +#define NETDATA_MAIN_THREAD_EXITING (CONFIG_BOOLEAN_YES + 1)
54 +#define NETDATA_MAIN_THREAD_EXITED CONFIG_BOOLEAN_NO
55 +
56 #define NETDATA_THREAD_TAG_MAX 100
57 const char *netdata_thread_tag(void);
58 int netdata_thread_tag_exists(void);