@cryptotaxi247 / netdata-1 / commits / 064bb4c97

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