[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380569 - in /team/mmichelson/pool_s...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 30 14:31:17 CST 2013


Author: mmichelson
Date: Wed Jan 30 14:31:13 2013
New Revision: 380569

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380569
Log:
Enqueue module unloading tasks to the threadpool.

When Asterisk is daemonized, attempting to stop it gracefully
will result in a crash because the thread attempting to stop
PJSIP services will not be registered with PJLIB.


Modified:
    team/mmichelson/pool_shark/res/res_sip.c
    team/mmichelson/pool_shark/res/res_sip/config_transport.c

Modified: team/mmichelson/pool_shark/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/res/res_sip.c?view=diff&rev=380569&r1=380568&r2=380569
==============================================================================
--- team/mmichelson/pool_shark/res/res_sip.c (original)
+++ team/mmichelson/pool_shark/res/res_sip.c Wed Jan 30 14:31:13 2013
@@ -46,27 +46,52 @@
 
 static struct ast_threadpool *sip_threadpool;
 
-int ast_sip_register_service(pjsip_module *module)
-{
+static int register_service(void *data)
+{
+	pjsip_module **module = data;
 	if (!ast_pjsip_endpoint) {
 		ast_log(LOG_ERROR, "There is no PJSIP endpoint. Unable to register services\n");
 		return -1;
 	}
-	if (pjsip_endpt_register_module(ast_pjsip_endpoint, module) != PJ_SUCCESS) {
-		ast_log(LOG_ERROR, "Unable to register module %.*s\n", (int) pj_strlen(&module->name), pj_strbuf(&module->name));
-		return -1;
-	}
-	ast_debug(1, "Registered SIP service %.*s\n", (int) pj_strlen(&module->name), pj_strbuf(&module->name));
+	if (pjsip_endpt_register_module(ast_pjsip_endpoint, *module) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Unable to register module %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
+		return -1;
+	}
+	ast_debug(1, "Registered SIP service %.*s (%p)\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name), *module);
+	return 0;
+}
+
+int ast_sip_register_service(pjsip_module *module)
+{
+	struct ast_sip_work *work = ast_sip_create_work();
+	int res;
+	if (!work) {
+		return -1;
+	}
+	res = ast_sip_push_task_synchronous(work, register_service, &module);
+	ast_sip_destroy_work(work);
+	return res;
+}
+
+static int unregister_service(void *data)
+{
+	pjsip_module **module = data;
+	if (!ast_pjsip_endpoint) {
+		return -1;
+	}
+	pjsip_endpt_unregister_module(ast_pjsip_endpoint, *module);
+	ast_debug(1, "Unregistered SIP service %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
 	return 0;
 }
 
 void ast_sip_unregister_service(pjsip_module *module)
 {
-	if (!ast_pjsip_endpoint) {
+	struct ast_sip_work *work = ast_sip_create_work();
+	if (!work) {
 		return;
 	}
-	pjsip_endpt_unregister_module(ast_pjsip_endpoint, module);
-	ast_debug(1, "Unregistered SIP service %.*s\n", (int) pj_strlen(&module->name), pj_strbuf(&module->name));
+	ast_sip_push_task_synchronous(work, unregister_service, &module);
+	ast_sip_destroy_work(work);
 }
 
 AO2_GLOBAL_OBJ_STATIC(registered_authenticator);
@@ -634,9 +659,11 @@
 	}
 	if (memory_pool) {
 		pj_pool_release(memory_pool);
+		memory_pool = NULL;
 	}
 	if (ast_pjsip_endpoint) {
 		pjsip_endpt_destroy(ast_pjsip_endpoint);
+		ast_pjsip_endpoint = NULL;
 	}
 	pj_caching_pool_destroy(&caching_pool);
 	/* XXX Should have a way of stopping monitor thread */
@@ -652,22 +679,36 @@
 	return 0;
 }
 
+static int unload_pjsip(void *data)
+{
+	if (memory_pool) {
+		pj_pool_release(memory_pool);
+		memory_pool = NULL;
+	}
+	if (ast_pjsip_endpoint) {
+		pjsip_endpt_destroy(ast_pjsip_endpoint);
+		ast_pjsip_endpoint = NULL;
+	}
+	pj_caching_pool_destroy(&caching_pool);
+	return 0;
+}
+
 static int unload_module(void)
 {
+	struct ast_sip_work *work;
 	ast_res_sip_destroy_configuration();
 	if (monitor_thread) {
 		stop_monitor_thread();
 	}
-	if (memory_pool) {
-		/* This will cause a crash in Asterisk in debug mode, as the thread
-		 * calling this is not a pjsip thread
-		 */
-		pj_pool_release(memory_pool);
-	}
-	if (ast_pjsip_endpoint) {
-		pjsip_endpt_destroy(ast_pjsip_endpoint);
-	}
-	pj_caching_pool_destroy(&caching_pool);
+	work = ast_sip_create_work();
+	/* The thread this is called from cannot call PJSIP/PJLIB functions,
+	 * so we have to push the work to the threadpool to handle
+	 */
+	ast_sip_push_task_synchronous(work, unload_pjsip, NULL);
+	ast_sip_destroy_work(work);
+
+	//ast_threadpool_shutdown(sip_threadpool);
+
 	return 0;
 }
 

Modified: team/mmichelson/pool_shark/res/res_sip/config_transport.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/res/res_sip/config_transport.c?view=diff&rev=380569&r1=380568&r2=380569
==============================================================================
--- team/mmichelson/pool_shark/res/res_sip/config_transport.c (original)
+++ team/mmichelson/pool_shark/res/res_sip/config_transport.c Wed Jan 30 14:31:13 2013
@@ -27,14 +27,26 @@
 #include "asterisk/astobj2.h"
 #include "asterisk/sorcery.h"
 
+static int destroy_transport_state(void *data)
+{
+	pjsip_transport *transport = data;
+	pjsip_transport_shutdown(transport);
+	return 0;
+}
+
 /*! \brief Destructor for transport state information */
 static void transport_state_destroy(void *obj)
 {
 	struct ast_sip_transport_state *state = obj;
+	struct ast_sip_work *work = ast_sip_create_work();
+	if (!work) {
+		ast_log(LOG_WARNING, "Unable to create work structure in order to shutdown transport\n");
+	}
 
 	if (state->transport) {
-		pjsip_transport_shutdown(state->transport);
-	}
+		ast_sip_push_task_synchronous(work, destroy_transport_state, state->transport);
+	}
+	ast_sip_destroy_work(work);
 }
 
 /*! \brief Destructor for transport */




More information about the asterisk-commits mailing list