fix crash when cleaning up virtual nodes (#19467)
* when the receiver is null, there is no need to wait for anything * virtual nodes may be activated and reactivated
Costa Tsaousis committed
Jan 23, 2025 at 17:42 UTC
064bb4c971ed30403bc6f45b3b666b12a6d0d312
4 files changed
+33
-14
src/libnetdata/object-state/object-state.c
+16
@@ -22,6 +22,22 @@ void object_state_activate(OBJECT_STATE *os) {
22
&os->state_refcount, &expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED));
23
}
24
25
+void object_state_activate_if_not_activated(OBJECT_STATE *os) {
26
+ __atomic_add_fetch(&os->state_id, 1, __ATOMIC_RELAXED);
27
+
28
+ REFCOUNT expected = __atomic_load_n(&os->state_refcount, __ATOMIC_RELAXED);
29
+ REFCOUNT desired;
30
+
31
+ do {
32
+ if(expected != OBJECT_STATE_DEACTIVATED)
33
+ return;
34
+
35
+ desired = 0;
36
+
37
+ } while(!__atomic_compare_exchange_n(
38
+ &os->state_refcount, &expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED));
39
+}
40
+
41
void object_state_deactivate(OBJECT_STATE *os) {
42
__atomic_add_fetch(&os->state_id, 1, __ATOMIC_RELAXED);
43
src/libnetdata/object-state/object-state.h
+1
@@ -23,6 +23,7 @@ OBJECT_STATE_ID object_state_id(OBJECT_STATE *os);
23
// increments the object's state id
24
// enables using the object - users may acquire and release the object
25
void object_state_activate(OBJECT_STATE *os);
26
+void object_state_activate_if_not_activated(OBJECT_STATE *os);
27
28
// increments the object's state id
29
// prevents users from acquiring it, and waits until all of its holders have released it
src/plugins.d/pluginsd_parser.c
+1
-1
@@ -204,7 +204,7 @@ static inline PARSER_RC pluginsd_host_define_end(char **words __maybe_unused, si
204
205
rrdhost_option_set(host, RRDHOST_OPTION_VIRTUAL_HOST);
206
rrdhost_flag_set(host, RRDHOST_FLAG_COLLECTOR_ONLINE);
207
- object_state_activate(&host->state_id);
207
+ object_state_activate_if_not_activated(&host->state_id);
208
ml_host_start(host);
209
dyncfg_host_init(host);
210
pulse_host_status(host, 0, 0); // this will detect the receiver status
src/streaming/stream-receiver.c
+15
-13
@@ -1224,23 +1224,25 @@ bool stream_receiver_signal_to_stop_and_wait(RRDHOST *host, STREAM_HANDSHAKE rea
1224
__atomic_store_n(&rpt->exit.shutdown, true, __ATOMIC_RELEASE);
1225
shutdown(rpt->sock.fd, SHUT_RDWR);
1226
}
1227
- }
1227
1229
- int count = 2000;
1230
- while (host->receiver == rpt && count-- > 0) {
1231
- rrdhost_receiver_unlock(host);
1228
+ int count = 2000;
1229
+ while (host->receiver == rpt && count-- > 0) {
1230
+ rrdhost_receiver_unlock(host);
1231
1233
- // let the lock for the receiver thread to exit
1234
- sleep_usec(1 * USEC_PER_MS);
1232
+ // let the lock for the receiver thread to exit
1233
+ sleep_usec(1 * USEC_PER_MS);
1234
1236
- rrdhost_receiver_lock(host);
1237
- }
1235
+ rrdhost_receiver_lock(host);
1236
+ }
1237
1239
- if(host->receiver == rpt)
1240
- netdata_log_error("STREAM RCV[x] '%s' [from [%s]:%s]: "
1241
- "streaming thread takes too long to stop, giving up..."
1242
- , rrdhost_hostname(host)
1243
- , rpt->remote_ip, rpt->remote_port);
1238
+ if(host->receiver == rpt)
1239
+ netdata_log_error("STREAM RCV[x] '%s' [from [%s]:%s]: "
1240
+ "streaming thread takes too long to stop, giving up..."
1241
+ , rrdhost_hostname(host)
1242
+ , rpt->remote_ip, rpt->remote_port);
1243
+ else
1244
+ ret = true;
1245
+ }
1246
else
1247
ret = true;
1248