diff options
author | Joshua Colp <jcolp@digium.com> | 2017-03-28 15:41:25 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-03-28 15:41:25 -0500 |
commit | 89c479a35c75c99ffa69183f98b9ff2b0553a4f8 (patch) | |
tree | 9a195d49ee1c5520de3ed7321fc4b2b3fae27a41 /res/res_xmpp.c | |
parent | 63a79e395a5509787174b5abf5c74d154eed1299 (diff) | |
parent | cd93488a82cd5d2ca44b292600c8fb5a9d25951b (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.c | 22 |
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); |