@cryptotaxi247 / netdata / commits / 21e6f6fc0

Improve thread shutdown handling for MSSQL plugin (#20725)

Stelios Fragkakis committed Jul 28, 2025 at 20:49 UTC 21e6f6fc0d13b7028c5693afffe98a90de1f89ed
3 files changed +97 -34
src/collectors/windows.plugin/perflib-mssql.c
+9 -1
@@ -1142,6 +1142,8 @@ void *netdata_mssql_queries(void *ptr __maybe_unused)
1142 return NULL;
1143 }
1144
1145 +static ND_THREAD *mssql_queries_thread = NULL;
1146 +
1147 static int initialize(int update_every)
1148 {
1149 static bool create_thread = false;
@@ -1155,7 +1157,7 @@ static int initialize(int update_every)
1157 }
1158
1159 if (create_thread)
1158 - nd_thread_create("mssql_queries", NETDATA_THREAD_OPTION_DEFAULT, netdata_mssql_queries, &update_every);
1160 + mssql_queries_thread = nd_thread_create("mssql_queries", NETDATA_THREAD_OPTION_DEFAULT, netdata_mssql_queries, &update_every);
1161
1162 return 0;
1163 }
@@ -2565,3 +2567,9 @@ int do_PerflibMSSQL(int update_every, usec_t dt __maybe_unused)
2567
2568 return 0;
2569 }
2570 +
2571 +void do_PerflibMSSQL_cleanup()
2572 +{
2573 + if (nd_thread_join(mssql_queries_thread))
2574 + nd_log_daemon(NDLP_ERR, "Failed to join mssql queries thread");
2575 +}
src/collectors/windows.plugin/windows_plugin.c
+87 -33
@@ -12,6 +12,7 @@ static struct proc_module {
12 int (*func)(int update_every, usec_t dt);
13 RRDDIM *rd;
14 ND_THREAD *thread;
15 + void (*cleanup)();
16 } win_modules[] = {
17
18 // system metrics
@@ -19,17 +20,26 @@ static struct proc_module {
20 .dim = "GetSystemUptime",
21 .enabled = CONFIG_BOOLEAN_YES,
22 .update_every = UPDATE_EVERY_MIN,
22 - .func = do_GetSystemUptime},
23 + .func = do_GetSystemUptime,
24 + .rd = NULL,
25 + .thread = NULL,
26 + .cleanup = NULL},
27 {.name = "GetSystemRAM",
28 .dim = "GetSystemRAM",
29 .enabled = CONFIG_BOOLEAN_YES,
30 .update_every = UPDATE_EVERY_MIN,
27 - .func = do_GetSystemRAM},
31 + .func = do_GetSystemRAM,
32 + .rd = NULL,
33 + .thread = NULL,
34 + .cleanup = NULL},
35 {.name = "GetPowerSupply",
36 .dim = "GetPowerSupply",
37 .enabled = CONFIG_BOOLEAN_YES,
38 .update_every = UPDATE_EVERY_MIN,
32 - .func = do_GetPowerSupply},
39 + .func = do_GetPowerSupply,
40 + .rd = NULL,
41 + .thread = NULL,
42 + .cleanup = NULL},
43 {.name = "PerflibServices",
44 .dim = "PerflibServices",
45 .enabled = CONFIG_BOOLEAN_YES,
@@ -44,99 +54,141 @@ static struct proc_module {
54 .dim = "PerflibProcesses",
55 .enabled = CONFIG_BOOLEAN_YES,
56 .update_every = UPDATE_EVERY_MIN,
47 - .func = do_PerflibProcesses},
57 + .func = do_PerflibProcesses,
58 + .rd = NULL,
59 + .thread = NULL,
60 + .cleanup = NULL},
61 {.name = "PerflibProcessor",
62 .dim = "PerflibProcessor",
63 .enabled = CONFIG_BOOLEAN_YES,
64 .update_every = UPDATE_EVERY_MIN,
52 - .func = do_PerflibProcessor},
65 + .func = do_PerflibProcessor,
66 + .rd = NULL,
67 + .thread = NULL,
68 + .cleanup = NULL},
69 {.name = "PerflibMemory",
70 .dim = "PerflibMemory",
71 .enabled = CONFIG_BOOLEAN_YES,
72 .update_every = UPDATE_EVERY_MIN,
57 - .func = do_PerflibMemory},
73 + .func = do_PerflibMemory,
74 + .rd = NULL,
75 + .thread = NULL,
76 + .cleanup = NULL},
77 {.name = "PerflibStorage",
78 .dim = "PerflibStorage",
79 .enabled = CONFIG_BOOLEAN_YES,
80 .update_every = UPDATE_EVERY_MIN,
62 - .func = do_PerflibStorage},
81 + .func = do_PerflibStorage,
82 + .rd = NULL,
83 + .thread = NULL,
84 + .cleanup = NULL},
85 {.name = "PerflibNetwork",
86 .dim = "PerflibNetwork",
87 .enabled = CONFIG_BOOLEAN_YES,
88 .update_every = UPDATE_EVERY_MIN,
67 - .func = do_PerflibNetwork},
89 + .func = do_PerflibNetwork,
90 + .rd = NULL,
91 + .thread = NULL,
92 + .cleanup = NULL},
93 {.name = "PerflibObjects",
94 .dim = "PerflibObjects",
95 .enabled = CONFIG_BOOLEAN_YES,
96 .update_every = UPDATE_EVERY_MIN,
72 - .func = do_PerflibObjects},
97 + .func = do_PerflibObjects,
98 + .rd = NULL,
99 + .thread = NULL,
100 + .cleanup = NULL},
101 {.name = "PerflibHyperV",
102 .dim = "PerflibHyperV",
103 .enabled = CONFIG_BOOLEAN_YES,
104 .update_every = 5 * UPDATE_EVERY_MIN,
77 - .func = do_PerflibHyperV},
78 -
105 + .func = do_PerflibHyperV,
106 + .rd = NULL,
107 + .thread = NULL,
108 + .cleanup = NULL},
109 {.name = "PerflibThermalZone",
110 .dim = "PerflibThermalZone",
111 .enabled = CONFIG_BOOLEAN_NO,
112 .update_every = 5 * UPDATE_EVERY_MIN,
83 - .func = do_PerflibThermalZone},
84 -
113 + .func = do_PerflibThermalZone,
114 + .rd = NULL,
115 + .thread = NULL,
116 + .cleanup = NULL},
117 {.name = "PerflibWebService",
118 .dim = "PerflibWebService",
119 .enabled = CONFIG_BOOLEAN_YES,
120 .update_every = UPDATE_EVERY_MIN,
89 - .func = do_PerflibWebService},
121 + .func = do_PerflibWebService,
122 + .rd = NULL,
123 + .thread = NULL,
124 + .cleanup = NULL},
125 {.name = "PerflibMSSQL",
126 .dim = "PerflibMSSQL",
127 .enabled = CONFIG_BOOLEAN_YES,
128 .update_every = 10 * UPDATE_EVERY_MIN,
94 - .func = do_PerflibMSSQL},
95 -
129 + .func = do_PerflibMSSQL,
130 + .rd = NULL,
131 + .thread = NULL,
132 + .cleanup = do_PerflibMSSQL_cleanup},
133 {.name = "PerflibNetFramework",
134 .dim = "PerflibNetFramework",
135 .enabled = CONFIG_BOOLEAN_YES,
136 .update_every = UPDATE_EVERY_MIN,
100 - .func = do_PerflibNetFramework},
137 + .func = do_PerflibNetFramework,
138 + .rd = NULL,
139 + .thread = NULL,
140 + .cleanup = NULL},
141 {.name = "PerflibAD",
142 .dim = "PerflibAD",
143 .enabled = CONFIG_BOOLEAN_YES,
144 .update_every = 10 * UPDATE_EVERY_MIN,
105 - .func = do_PerflibAD},
106 -
145 + .func = do_PerflibAD,
146 + .rd = NULL,
147 + .thread = NULL,
148 + .cleanup = NULL},
149 {.name = "PerflibADCS",
150 .dim = "PerflibADCS",
151 .enabled = CONFIG_BOOLEAN_YES,
152 .update_every = 10 * UPDATE_EVERY_MIN,
111 - .func = do_PerflibADCS},
112 -
153 + .func = do_PerflibADCS,
154 + .rd = NULL,
155 + .thread = NULL,
156 + .cleanup = NULL},
157 {.name = "PerflibADFS",
158 .dim = "PerflibADFS",
159 .enabled = CONFIG_BOOLEAN_YES,
160 .update_every = 10 * UPDATE_EVERY_MIN,
117 - .func = do_PerflibADFS},
118 -
161 + .func = do_PerflibADFS,
162 + .rd = NULL,
163 + .thread = NULL,
164 + .cleanup = NULL},
165 {.name = "PerflibExchange",
166 .dim = "PerflibExchange",
167 .enabled = CONFIG_BOOLEAN_YES,
168 .update_every = 10 * UPDATE_EVERY_MIN,
123 - .func = do_PerflibExchange},
124 -
169 + .func = do_PerflibExchange,
170 + .rd = NULL,
171 + .thread = NULL,
172 + .cleanup = NULL},
173 {.name = "PerflibNUMA",
174 .dim = "PerflibNUMA",
175 .enabled = CONFIG_BOOLEAN_YES,
176 .update_every = UPDATE_EVERY_MIN,
129 - .func = do_PerflibNUMA},
130 -
177 + .func = do_PerflibNUMA,
178 + .rd = NULL,
179 + .thread = NULL,
180 + .cleanup = NULL},
181 // the terminator of this array
182 {.name = "PerflibASP",
183 .dim = "PerflibASP",
184 .enabled = CONFIG_BOOLEAN_YES,
185 .update_every = UPDATE_EVERY_MIN,
136 - .func = do_PerflibASP},
137 -
186 + .func = do_PerflibASP,
187 + .rd = NULL,
188 + .thread = NULL,
189 + .cleanup = NULL},
190 // the terminator of this array
139 - {.name = NULL, .dim = NULL, .func = NULL}};
191 + {.name = NULL, .dim = NULL, .func = NULL, .rd = NULL, .thread = NULL, .cleanup = NULL}};
192
193 #if WORKER_UTILIZATION_MAX_JOB_TYPES < 36
194 #error WORKER_UTILIZATION_MAX_JOB_TYPES has to be at least 36
@@ -206,8 +258,6 @@ void *win_plugin_main(void *ptr)
258 int update_every = localhost->rrd_update_every;
259 for (i = 0; win_modules[i].name; i++) {
260 struct proc_module *pm = &win_modules[i];
209 - pm->thread = NULL;
210 -
261 snprintfz(buf, CONFIG_MAX_NAME, "plugin:windows:%s", pm->name);
262
263 pm->enabled = inicfg_get_boolean(&netdata_config, "plugin:windows", pm->name, pm->enabled);
@@ -267,8 +317,12 @@ void *win_plugin_main(void *ptr)
317 // Join threads
318 for (i = 0; win_modules[i].name; i++) {
319 struct proc_module *pm = &win_modules[i];
270 - if (pm->thread)
320 + if (pm->cleanup)
321 + pm->cleanup();
322 +
323 + if (pm->thread) {
324 nd_thread_join(pm->thread);
325 + }
326 }
327 return NULL;
328 }
src/collectors/windows.plugin/windows_plugin.h
+1
@@ -36,6 +36,7 @@ int do_PerflibObjects(int update_every, usec_t dt);
36 int do_PerflibThermalZone(int update_every, usec_t dt);
37 int do_PerflibWebService(int update_every, usec_t dt);
38 int do_PerflibMSSQL(int update_every, usec_t dt);
39 +void do_PerflibMSSQL_cleanup();
40 int do_PerflibNetFramework(int update_every, usec_t dt);
41 int do_PerflibAD(int update_every, usec_t dt);
42 int do_PerflibADCS(int update_every, usec_t dt);