From 49ebb585693aa3361b9ec235c1a2d28407a2091d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 15 Aug 2022 22:17:00 +0100 Subject: [PATCH] Fix failure to close thread in some situations. Closes #2545. Thanks to p-luke. --- ChangeLog.txt | 1 + lib/connect.c | 2 ++ lib/loop.c | 7 ++----- lib/mosquitto_internal.h | 1 + lib/util_mosq.c | 20 ++++++++++++++++++++ lib/util_mosq.h | 4 ++++ 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 5a165de1a3..79f2ee7789 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -36,6 +36,7 @@ Client library: - Fix documentation omission around mosquitto_reinitialise. Closes #2489. - Fix use of MOSQ_OPT_SSL_CTX when used in conjunction with MOSQ_OPT_SSL_CTX_DEFAULTS. Closes #2463. +- Fix failure to close thread in some situations. Closes #2545. Clients: - Fix mosquitto_pub incorrectly reusing topic aliases when reconnecting. diff --git a/lib/connect.c b/lib/connect.c index ab61b66c25..dfc57fa25f 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -76,6 +76,7 @@ static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int mosq->msgs_in.inflight_quota = mosq->msgs_in.inflight_maximum; mosq->msgs_out.inflight_quota = mosq->msgs_out.inflight_maximum; mosq->retain_available = 1; + mosquitto__set_request_disconnect(mosq, false); return MOSQ_ERR_SUCCESS; } @@ -255,6 +256,7 @@ int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosqu } mosquitto__set_state(mosq, mosq_cs_disconnected); + mosquitto__set_request_disconnect(mosq, true); if(mosq->sock == INVALID_SOCKET){ return MOSQ_ERR_NO_CONN; }else{ diff --git a/lib/loop.c b/lib/loop.c index eb12854efc..965294f052 100644 --- a/lib/loop.c +++ b/lib/loop.c @@ -242,7 +242,6 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) int run = 1; int rc = MOSQ_ERR_SUCCESS; unsigned long reconnect_delay; - enum mosquitto_client_state state; if(!mosq) return MOSQ_ERR_INVAL; @@ -281,8 +280,7 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) pthread_testcancel(); #endif rc = MOSQ_ERR_SUCCESS; - state = mosquitto__get_state(mosq); - if(state == mosq_cs_disconnecting || state == mosq_cs_disconnected){ + if(mosquitto__get_request_disconnect(mosq)){ run = 0; }else{ if(mosq->reconnect_delay_max > mosq->reconnect_delay){ @@ -304,8 +302,7 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) rc = interruptible_sleep(mosq, (time_t)reconnect_delay); if(rc) return rc; - state = mosquitto__get_state(mosq); - if(state == mosq_cs_disconnecting || state == mosq_cs_disconnected){ + if(mosquitto__get_request_disconnect(mosq)){ run = 0; }else{ rc = mosquitto_reconnect(mosq); diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h index 87718ea9bf..ac71ffbf3e 100644 --- a/lib/mosquitto_internal.h +++ b/lib/mosquitto_internal.h @@ -339,6 +339,7 @@ struct mosquitto { unsigned int reconnect_delay; unsigned int reconnect_delay_max; bool reconnect_exponential_backoff; + bool request_disconnect; char threaded; struct mosquitto__packet *out_packet_last; mosquitto_property *connect_properties; diff --git a/lib/util_mosq.c b/lib/util_mosq.c index f4f868b963..22f8c4d5d5 100644 --- a/lib/util_mosq.c +++ b/lib/util_mosq.c @@ -302,3 +302,23 @@ enum mosquitto_client_state mosquitto__get_state(struct mosquitto *mosq) return state; } + +#ifndef WITH_BROKER +void mosquitto__set_request_disconnect(struct mosquitto *mosq, bool request_disconnect) +{ + pthread_mutex_lock(&mosq->state_mutex); + mosq->request_disconnect = request_disconnect; + pthread_mutex_unlock(&mosq->state_mutex); +} + +bool mosquitto__get_request_disconnect(struct mosquitto *mosq) +{ + bool request_disconnect; + + pthread_mutex_lock(&mosq->state_mutex); + request_disconnect = mosq->request_disconnect; + pthread_mutex_unlock(&mosq->state_mutex); + + return request_disconnect; +} +#endif diff --git a/lib/util_mosq.h b/lib/util_mosq.h index 7d993442d3..ecc0120c60 100644 --- a/lib/util_mosq.h +++ b/lib/util_mosq.h @@ -32,6 +32,10 @@ uint16_t mosquitto__mid_generate(struct mosquitto *mosq); int mosquitto__set_state(struct mosquitto *mosq, enum mosquitto_client_state state); enum mosquitto_client_state mosquitto__get_state(struct mosquitto *mosq); +#ifndef WITH_BROKER +void mosquitto__set_request_disconnect(struct mosquitto *mosq, bool request_disconnect); +bool mosquitto__get_request_disconnect(struct mosquitto *mosq); +#endif #ifdef WITH_TLS int mosquitto__hex2bin_sha1(const char *hex, unsigned char **bin);