From 8e4f6238558c28cd05bd580cc947d7178d2bac90 Mon Sep 17 00:00:00 2001
From: Guus Sliepen <guus@meshlink.io>
Date: Wed, 10 Jun 2020 22:25:12 +0200
Subject: [PATCH] Properly initialize mutexes and condition variables.

On Linux, zeroing a pthread_mutex_t or pthread_cond_t variable ensures
the mutex/cond is properly initialized, however this is not the case om
some other platforms. Ensure we always call pthread_mutex/cond_init().
---
 src/adns.c      | 2 ++
 src/discovery.c | 7 +++++--
 src/meshlink.c  | 7 ++++++-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/adns.c b/src/adns.c
index 01989ac5..cb9611e1 100644
--- a/src/adns.c
+++ b/src/adns.c
@@ -184,6 +184,8 @@ struct addrinfo *adns_blocking_request(meshlink_handle_t *mesh, char *host, char
 	info->host = host;
 	info->serv = serv;
 	info->socktype = socktype;
+	pthread_mutex_init(&info->mutex, NULL);
+	pthread_cond_init(&info->cond, NULL);
 
 	struct timespec deadline;
 	clock_gettime(CLOCK_REALTIME, &deadline);
diff --git a/src/discovery.c b/src/discovery.c
index df88b179..d4790c43 100644
--- a/src/discovery.c
+++ b/src/discovery.c
@@ -343,6 +343,8 @@ static void *discovery_loop(void *userdata) {
 	meshlink_handle_t *mesh = userdata;
 	assert(mesh);
 
+	pthread_mutex_lock(&mesh->discovery_mutex);
+
 	// handle catta logs
 	catta_set_log_function(discovery_log_cb);
 
@@ -414,7 +416,6 @@ static void *discovery_loop(void *userdata) {
 
 fail:
 
-	pthread_mutex_lock(&mesh->discovery_mutex);
 	pthread_cond_broadcast(&mesh->discovery_cond);
 	pthread_mutex_unlock(&mesh->discovery_mutex);
 
@@ -461,14 +462,16 @@ bool discovery_start(meshlink_handle_t *mesh) {
 	assert(!mesh->discovery_threadstarted);
 	assert(!mesh->catta_servicetype);
 
+	pthread_mutex_lock(&mesh->discovery_mutex);
+
 	// Start the discovery thread
 	if(pthread_create(&mesh->discovery_thread, NULL, discovery_loop, mesh) != 0) {
+		pthread_mutex_unlock(&mesh->discovery_mutex);
 		logger(mesh, MESHLINK_ERROR, "Could not start discovery thread: %s\n", strerror(errno));
 		memset(&mesh->discovery_thread, 0, sizeof(mesh)->discovery_thread);
 		return false;
 	}
 
-	pthread_mutex_lock(&mesh->discovery_mutex);
 	pthread_cond_wait(&mesh->discovery_cond, &mesh->discovery_mutex);
 	pthread_mutex_unlock(&mesh->discovery_mutex);
 
diff --git a/src/meshlink.c b/src/meshlink.c
index 9aca0677..8ad72c15 100644
--- a/src/meshlink.c
+++ b/src/meshlink.c
@@ -1456,12 +1456,17 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
 		}
 	}
 
-	// initialize mutex
+	// initialize mutexes and conds
 	pthread_mutexattr_t attr;
 	pthread_mutexattr_init(&attr);
 	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 	pthread_mutex_init(&mesh->mutex, &attr);
 
+	pthread_mutex_init(&mesh->discovery_mutex, NULL);
+	pthread_cond_init(&mesh->discovery_cond, NULL);
+
+	pthread_cond_init(&mesh->adns_cond, NULL);
+
 	mesh->threadstarted = false;
 	event_loop_init(&mesh->loop);
 	mesh->loop.data = mesh;
-- 
2.39.5