summaryrefslogtreecommitdiffstats
path: root/database/rrdhost.c
diff options
context:
space:
mode:
authorAndrew Moss <1043609+amoss@users.noreply.github.com>2020-06-19 19:37:47 +0200
committerGitHub <noreply@github.com>2020-06-19 19:37:47 +0200
commit85752833adac111cf01ae558ee0c46b3a76aed69 (patch)
tree1594cb6ddbe49ad98b43b4ffb25c25fc760d60d9 /database/rrdhost.c
parent51cff0660b0eb671dbec42e54d7567db8b6ba712 (diff)
Fixes the race-hazard in streaming during the shutdown sequence (#9370)
The streaming component detects when a receiver stream has closed, and stops an attached sender on the same host. This is to support proxy configurations where the stream is passed through. During the shutdown sequence, once netdata_exit has been set no thread should touch any RRDHOST structure as the non-static threads are not joined before the database shuts down. The destruction of the thread state has been separated from the cleanup and can be called from two points. If the thread can detach itself from the host (i.e. it is not during the shutdown sequence) then it does so and destroys the state. During shutdown the thread leaves the state intact so that it can be destroyed during the host destruction, and the host destruction now cancels the thread to ensure a consistent sequence of events.
Diffstat (limited to 'database/rrdhost.c')
-rw-r--r--database/rrdhost.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/database/rrdhost.c b/database/rrdhost.c
index 7f1c4e9de6..d349830730 100644
--- a/database/rrdhost.c
+++ b/database/rrdhost.c
@@ -666,6 +666,7 @@ void rrdhost_system_info_free(struct rrdhost_system_info *system_info) {
}
}
+void destroy_receiver_state(struct receiver_state *rpt);
void rrdhost_free(RRDHOST *host) {
if(!host) return;
@@ -674,12 +675,25 @@ void rrdhost_free(RRDHOST *host) {
rrd_check_wrlock(); // make sure the RRDs are write locked
// ------------------------------------------------------------------------
- // clean up the sender
+ // clean up streaming
rrdpush_sender_thread_stop(host); // stop a possibly running thread
cbuffer_free(host->sender->buffer);
buffer_free(host->sender->build);
freez(host->sender);
host->sender = NULL;
+ if (netdata_exit) {
+ netdata_mutex_lock(&host->receiver_lock);
+ if (host->receiver) {
+ if (!host->receiver->exited)
+ netdata_thread_cancel(host->receiver->thread);
+ while (!host->receiver->exited)
+ sleep_usec(50 * USEC_PER_MS);
+ destroy_receiver_state(host->receiver);
+ }
+ netdata_mutex_unlock(&host->receiver_lock);
+ }
+
+
rrdhost_wrlock(host); // lock this RRDHOST