summaryrefslogtreecommitdiff
path: root/res/res_xmpp.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-03-28 15:41:25 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2017-03-28 15:41:25 -0500
commit89c479a35c75c99ffa69183f98b9ff2b0553a4f8 (patch)
tree9a195d49ee1c5520de3ed7321fc4b2b3fae27a41 /res/res_xmpp.c
parent63a79e395a5509787174b5abf5c74d154eed1299 (diff)
parentcd93488a82cd5d2ca44b292600c8fb5a9d25951b (diff)
Merge "res_xmpp: Use incremental backoff when a read error occurs" into 14
Diffstat (limited to 'res/res_xmpp.c')
-rw-r--r--res/res_xmpp.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/res/res_xmpp.c b/res/res_xmpp.c
index 6642a9be8..591a7e645 100644
--- a/res/res_xmpp.c
+++ b/res/res_xmpp.c
@@ -3582,6 +3582,7 @@ int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
{
if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
xmpp_client_change_state(client, XMPP_STATE_DISCONNECTING);
+ pthread_cancel(client->thread);
pthread_join(client->thread, NULL);
client->thread = AST_PTHREADT_NULL;
}
@@ -3761,11 +3762,26 @@ static int xmpp_client_receive(struct ast_xmpp_client *client, unsigned int time
return IKS_OK;
}
+static void sleep_with_backoff(unsigned int *sleep_time)
+{
+ /* We're OK with our thread dying here */
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+ sleep(*sleep_time);
+ *sleep_time = MIN(60, *sleep_time * 2);
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+}
+
/*! \brief XMPP client connection thread */
static void *xmpp_client_thread(void *data)
{
struct ast_xmpp_client *client = data;
int res = IKS_NET_RWERR;
+ unsigned int sleep_time = 1;
+
+ /* We only allow cancellation while sleeping */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
do {
if (client->state == XMPP_STATE_DISCONNECTING) {
@@ -3776,7 +3792,7 @@ static void *xmpp_client_thread(void *data)
if (res == IKS_NET_RWERR || client->timeout == 0) {
ast_debug(3, "[%s] Connecting\n", client->name);
if ((res = xmpp_client_reconnect(client)) != IKS_OK) {
- sleep(4);
+ sleep_with_backoff(&sleep_time);
res = IKS_NET_RWERR;
}
continue;
@@ -3815,6 +3831,8 @@ static void *xmpp_client_thread(void *data)
}
} else if (res == IKS_NET_RWERR) {
ast_log(LOG_WARNING, "[%s] Socket read error\n", client->name);
+ ast_xmpp_client_disconnect(client);
+ sleep_with_backoff(&sleep_time);
} else if (res == IKS_NET_NOSOCK) {
ast_log(LOG_WARNING, "[%s] No socket\n", client->name);
} else if (res == IKS_NET_NOCONN) {
@@ -3827,6 +3845,8 @@ static void *xmpp_client_thread(void *data)
ast_log(LOG_WARNING, "[%s] Dropped?\n", client->name);
} else if (res == IKS_NET_UNKNOWN) {
ast_debug(5, "[%s] Unknown\n", client->name);
+ } else if (res == IKS_OK) {
+ sleep_time = 1;
}
} while (1);