[Asterisk-code-review] res xmpp: Prevent deadlock on module unload (asterisk[master])

Sean Bright asteriskteam at digium.com
Wed Mar 29 16:11:46 CDT 2017


Sean Bright has uploaded a new change for review. ( https://gerrit.asterisk.org/5363 )

Change subject: res_xmpp: Prevent deadlock on module unload
......................................................................

res_xmpp: Prevent deadlock on module unload

Calling ao2_global_obj_release() in unload_module will call our
destructor, causing all of our ast_xmpp_client instances to be
disconencted.

If there are subscriptions, however, closing the ast_xmpp_client will
attempt to unsubscribe, and in the process attempt to acquire a read
lock on the 'globals' object. Unfortunately, during
ao2_global_obj_release() we already hold the write lock, so this fails.

Instead, when unloading, we explicitly shutdown all of our clients
first while holding a read lock. When ao2_global_obj_release() is
subsequently called, no additional locking is attempted and we cleanly
unload.

ASTERISK-21009 #close
Reported by: Marcello Ceschia

Change-Id: Idf40ae136b5070dba22cb576ea8414fbc9939385
---
M res/res_xmpp.c
1 file changed, 17 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/63/5363/1

diff --git a/res/res_xmpp.c b/res/res_xmpp.c
index cc9d56f..de837ac 100644
--- a/res/res_xmpp.c
+++ b/res/res_xmpp.c
@@ -4486,8 +4486,25 @@
 	AST_CLI_DEFINE(xmpp_cli_purge_pubsub_nodes, "Purges PubSub nodes"),
 };
 
+static int shutdown_client(void *obj, void *arg, int flags)
+{
+	struct ast_xmpp_client_config *cfg = obj;
+	ast_xmpp_client_disconnect(cfg->client);
+	return 0;
+}
+
+static void shutdown_all_clients(void)
+{
+	RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
+
+	ao2_callback(cfg->clients, OBJ_NODATA | OBJ_MULTIPLE, shutdown_client, NULL);
+}
+
 static int unload_module(void)
 {
+	/* Shutdown all clients gracefully before it is done during globals destruction */
+	shutdown_all_clients();
+
 	ast_msg_tech_unregister(&msg_tech);
 	ast_cli_unregister_multiple(xmpp_cli, ARRAY_LEN(xmpp_cli));
 	ast_unregister_application(app_ajisend);

-- 
To view, visit https://gerrit.asterisk.org/5363
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idf40ae136b5070dba22cb576ea8414fbc9939385
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Sean Bright <sean.bright at gmail.com>



More information about the asterisk-code-review mailing list