summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Moss <1043609+amoss@users.noreply.github.com>2020-06-04 18:24:04 +0200
committerGitHub <noreply@github.com>2020-06-04 18:24:04 +0200
commitea7d7ea31d2d48730ccaf37e1c96c43f6b255fa8 (patch)
treec2d35dbd066652613702c495f6ae04947accae88
parentfecbb89d0c33e2bbe84aa14c0b3204cb60134218 (diff)
Fix Coverity defects 359164, 359165 and 358989. (#9268)
Removed uses of the host lock that could deadlock senders and replaced with the new fine-grained mutex.
-rw-r--r--daemon/commands.c2
-rw-r--r--streaming/rrdpush.c13
-rw-r--r--streaming/rrdpush.h6
-rw-r--r--streaming/sender.c4
4 files changed, 11 insertions, 14 deletions
diff --git a/daemon/commands.c b/daemon/commands.c
index 8ea868fee1..1944b6c370 100644
--- a/daemon/commands.c
+++ b/daemon/commands.c
@@ -673,7 +673,7 @@ void commands_init(void)
info("Initializing command server.");
for (i = 0 ; i < CMD_TOTAL_COMMANDS ; ++i) {
- uv_mutex_init(&command_lock_array[i]);
+ assert(0 == uv_mutex_init(&command_lock_array[i]));
}
assert(0 == uv_rwlock_init(&exclusive_rwlock));
diff --git a/streaming/rrdpush.c b/streaming/rrdpush.c
index 5dc3f832dc..316e9cdc60 100644
--- a/streaming/rrdpush.c
+++ b/streaming/rrdpush.c
@@ -368,12 +368,10 @@ void rrdpush_send_labels(RRDHOST *host) {
// rrdpush sender thread
// Either the receiver lost the connection or the host is being destroyed.
-// Don't lock the sender buffer - doesn't affect consistency in either case.
-// TODO-GAPS During the host destruction sequence we should make sure the disconnect happens early enough to lock
-// out collectors hitting the sender. Locking the mutex means there may be waiting threads when we free.
+// The sender mutex guards thread creation, any spurious data is wiped on reconnection.
void rrdpush_sender_thread_stop(RRDHOST *host) {
- rrdhost_wrlock(host);
+ netdata_mutex_lock(&host->sender->mutex);
netdata_thread_t thr = 0;
if(host->rrdpush_sender_spawn) {
@@ -390,7 +388,7 @@ void rrdpush_sender_thread_stop(RRDHOST *host) {
netdata_thread_cancel(host->rrdpush_sender_thread);
}
- rrdhost_unlock(host);
+ netdata_mutex_unlock(&host->sender->mutex);
if(thr != 0) {
info("STREAM %s [send]: waiting for the sending thread to stop...", host->hostname);
@@ -410,7 +408,7 @@ void log_stream_connection(const char *client_ip, const char *client_port, const
static void rrdpush_sender_thread_spawn(RRDHOST *host) {
- rrdhost_wrlock(host);
+ netdata_mutex_lock(&host->sender->mutex);
if(!host->rrdpush_sender_spawn) {
char tag[NETDATA_THREAD_TAG_MAX + 1];
@@ -421,8 +419,7 @@ static void rrdpush_sender_thread_spawn(RRDHOST *host) {
else
host->rrdpush_sender_spawn = 1;
}
-
- rrdhost_unlock(host);
+ netdata_mutex_unlock(&host->sender->mutex);
}
int rrdpush_receiver_permission_denied(struct web_client *w) {
diff --git a/streaming/rrdpush.h b/streaming/rrdpush.h
index bad63888b9..2f171a0e38 100644
--- a/streaming/rrdpush.h
+++ b/streaming/rrdpush.h
@@ -52,9 +52,9 @@ struct sender_state {
size_t send_attempts;
time_t last_sent_t;
size_t not_connected_loops;
- // metrics may be collected asynchronously
- // these synchronize all the threads willing the write to our sending buffer
- netdata_mutex_t mutex; // Guard access to buffer / build
+ // Metrics are collected asynchronously by collector threads calling rrdset_done_push(). This can also trigger
+ // the lazy creation of the sender thread - both cases (buffer access and thread creation) are guarded here.
+ netdata_mutex_t mutex;
struct circular_buffer *buffer;
BUFFER *build;
char read_buffer[512];
diff --git a/streaming/sender.c b/streaming/sender.c
index 4334e7e56e..01ae6e8763 100644
--- a/streaming/sender.c
+++ b/streaming/sender.c
@@ -520,7 +520,7 @@ void execute_commands(struct sender_state *s) {
static void rrdpush_sender_thread_cleanup_callback(void *ptr) {
RRDHOST *host = (RRDHOST *)ptr;
- rrdhost_wrlock(host);
+ netdata_mutex_lock(&host->sender->mutex);
info("STREAM %s [send]: sending thread cleans up...", host->hostname);
@@ -546,7 +546,7 @@ static void rrdpush_sender_thread_cleanup_callback(void *ptr) {
info("STREAM %s [send]: sending thread now exits.", host->hostname);
- rrdhost_unlock(host);
+ netdata_mutex_unlock(&host->sender->mutex);
}
void sender_init(struct sender_state *s, RRDHOST *parent) {