From 7f0b4d62713efce6e2cf49396307b55837eebcda Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 8 Aug 2018 09:19:53 +0100 Subject: [PATCH] Fix connection problems when using mosquitto_connect_async(). The connection wouldn't always complete if mosquitto_loop_start() was called before mosquitto_connect_async(). Closes #848. Thanks to Ian Gough. Bug: https://github.com/eclipse/mosquitto/issues/848 Signed-off-by: Roger A. Light --- ChangeLog.txt | 2 ++ lib/connect.c | 3 +++ lib/mosquitto_internal.h | 1 + lib/thread_mosq.c | 20 ++++++++++++++++---- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index c8222ffa..905da262 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -21,6 +21,8 @@ Library: - Fix some places where return codes were incorrect, including to the on_disconnect() callback. This has resulted in two new error codes, MOSQ_ERR_KEEPALIVE and MOSQ_ERR_LOOKUP. +- Fix connection problems when mosquitto_loop_start() was called before + mosquitto_connect_async(). Closes #848. 1.5 - 20180502 diff --git a/lib/connect.c b/lib/connect.c index ab14fd48..fe084e31 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -178,6 +178,9 @@ static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking) }else #endif { + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_connecting; + pthread_mutex_unlock(&mosq->state_mutex); rc = net__socket_connect(mosq, mosq->host, mosq->port, mosq->bind_address, blocking); } if(rc>0){ diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h index 05667a78..960c1f41 100644 --- a/lib/mosquitto_internal.h +++ b/lib/mosquitto_internal.h @@ -107,6 +107,7 @@ enum mosquitto_client_state { mosq_cs_socks5_userpass_reply = 13, mosq_cs_socks5_send_userpass = 14, mosq_cs_expiring = 15, + mosq_cs_connecting = 16, }; enum mosquitto__protocol { diff --git a/lib/thread_mosq.c b/lib/thread_mosq.c index 92b5578d..204da47e 100644 --- a/lib/thread_mosq.c +++ b/lib/thread_mosq.c @@ -79,15 +79,27 @@ int mosquitto_loop_stop(struct mosquitto *mosq, bool force) void *mosquitto__thread_main(void *obj) { struct mosquitto *mosq = obj; + int state; if(!mosq) return NULL; - pthread_mutex_lock(&mosq->state_mutex); - if(mosq->state == mosq_cs_connect_async){ + do{ + pthread_mutex_lock(&mosq->state_mutex); + state = mosq->state; pthread_mutex_unlock(&mosq->state_mutex); + if(state == mosq_cs_new){ +#ifdef WIN32 + Sleep(10); +#else + usleep(10000); +#endif + }else{ + break; + } + }while(1); + + if(state == mosq_cs_connect_async){ mosquitto_reconnect(mosq); - }else{ - pthread_mutex_unlock(&mosq->state_mutex); } if(!mosq->keepalive){