mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Merge "res_pjsip: Fix issues that prevented shutdown of modules." into 13
This commit is contained in:
		| @@ -541,6 +541,13 @@ int ast_sip_session_register_supplement(struct ast_sip_session_supplement *suppl | ||||
|  */ | ||||
| void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement); | ||||
|  | ||||
| /*! | ||||
|  * \brief Add supplements to a SIP session | ||||
|  * | ||||
|  * \param session The session to initialize | ||||
|  */ | ||||
| int ast_sip_session_add_supplements(struct ast_sip_session *session); | ||||
|  | ||||
| /*! | ||||
|  * \brief Alternative for ast_datastore_alloc() | ||||
|  * | ||||
|   | ||||
| @@ -3480,7 +3480,7 @@ int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, | ||||
|  | ||||
| AST_RWLIST_HEAD_STATIC(supplements, ast_sip_supplement); | ||||
|  | ||||
| int ast_sip_register_supplement(struct ast_sip_supplement *supplement) | ||||
| void internal_sip_register_supplement(struct ast_sip_supplement *supplement) | ||||
| { | ||||
| 	struct ast_sip_supplement *iter; | ||||
| 	int inserted = 0; | ||||
| @@ -3498,22 +3498,39 @@ int ast_sip_register_supplement(struct ast_sip_supplement *supplement) | ||||
| 	if (!inserted) { | ||||
| 		AST_RWLIST_INSERT_TAIL(&supplements, supplement, next); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int ast_sip_register_supplement(struct ast_sip_supplement *supplement) | ||||
| { | ||||
| 	internal_sip_register_supplement(supplement); | ||||
| 	ast_module_ref(ast_module_info->self); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement) | ||||
| int internal_sip_unregister_supplement(struct ast_sip_supplement *supplement) | ||||
| { | ||||
| 	struct ast_sip_supplement *iter; | ||||
| 	SCOPED_LOCK(lock, &supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); | ||||
| 	int res = -1; | ||||
|  | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&supplements, iter, next) { | ||||
| 		if (supplement == iter) { | ||||
| 			AST_RWLIST_REMOVE_CURRENT(next); | ||||
| 			ast_module_unref(ast_module_info->self); | ||||
| 			res = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_END; | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement) | ||||
| { | ||||
| 	if (!internal_sip_unregister_supplement(supplement)) { | ||||
| 		ast_module_unref(ast_module_info->self); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg) | ||||
| @@ -4580,6 +4597,16 @@ static int reload_configuration_task(void *obj) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void internal_res_pjsip_ref(void) | ||||
| { | ||||
| 	ast_module_ref(ast_module_info->self); | ||||
| } | ||||
|  | ||||
| void internal_res_pjsip_unref(void) | ||||
| { | ||||
| 	ast_module_unref(ast_module_info->self); | ||||
| } | ||||
|  | ||||
| static int unload_pjsip(void *data) | ||||
| { | ||||
| 	/* | ||||
|   | ||||
| @@ -338,6 +338,18 @@ int internal_sip_register_service(pjsip_module *module); | ||||
|  */ | ||||
| int internal_sip_unregister_service(pjsip_module *module); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Used by res_pjsip.so to register a supplement without adding a self reference | ||||
|  */ | ||||
| void internal_sip_register_supplement(struct ast_sip_supplement *supplement); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Used by res_pjsip.so to unregister a supplement without removing a self reference | ||||
|  */ | ||||
| int internal_sip_unregister_supplement(struct ast_sip_supplement *supplement); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Used by res_pjsip.so to register an endpoint formatter without adding a self reference | ||||
| @@ -350,6 +362,20 @@ void internal_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter | ||||
|  */ | ||||
| int internal_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj); | ||||
|  | ||||
| struct ast_sip_session_supplement; | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Used by res_pjsip.so to register a session supplement without adding a self reference | ||||
|  */ | ||||
| void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Used by res_pjsip.so to unregister a session supplement without removing a self reference | ||||
|  */ | ||||
| int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Finds or creates contact_status for a contact | ||||
| @@ -381,4 +407,16 @@ int ast_sip_initialize_scheduler(void); | ||||
|  */ | ||||
| int ast_sip_destroy_scheduler(void); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Add a reference to the res_pjsip module | ||||
|  */ | ||||
| void internal_res_pjsip_ref(void); | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Remove a reference from the res_pjsip module | ||||
|  */ | ||||
| void internal_res_pjsip_unref(void); | ||||
|  | ||||
| #endif /* RES_PJSIP_PRIVATE_H_ */ | ||||
|   | ||||
| @@ -505,32 +505,24 @@ static pj_bool_t filter_on_rx_message(pjsip_rx_data *rdata) | ||||
|  | ||||
| void ast_res_pjsip_cleanup_message_filter(void) | ||||
| { | ||||
| 	ast_sip_unregister_service(&filter_module_tsx); | ||||
| 	ast_sip_unregister_service(&filter_module_transport); | ||||
| 	ast_sip_unregister_supplement(&filter_supplement); | ||||
| 	ast_sip_session_unregister_supplement(&filter_session_supplement); | ||||
| 	internal_sip_unregister_service(&filter_module_tsx); | ||||
| 	internal_sip_unregister_service(&filter_module_transport); | ||||
| 	internal_sip_unregister_supplement(&filter_supplement); | ||||
| 	internal_sip_session_unregister_supplement(&filter_session_supplement); | ||||
| } | ||||
|  | ||||
| int ast_res_pjsip_init_message_filter(void) | ||||
| { | ||||
| 	if (ast_sip_session_register_supplement(&filter_session_supplement)) { | ||||
| 		ast_log(LOG_ERROR, "Could not register message filter session supplement for outgoing requests\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	internal_sip_session_register_supplement(&filter_session_supplement); | ||||
| 	internal_sip_register_supplement(&filter_supplement); | ||||
|  | ||||
| 	if (ast_sip_register_supplement(&filter_supplement)) { | ||||
| 		ast_log(LOG_ERROR, "Could not register message filter supplement for outgoing requests\n"); | ||||
| 		ast_res_pjsip_cleanup_message_filter(); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_sip_register_service(&filter_module_transport)) { | ||||
| 	if (internal_sip_register_service(&filter_module_transport)) { | ||||
| 		ast_log(LOG_ERROR, "Could not register message filter module for incoming and outgoing requests\n"); | ||||
| 		ast_res_pjsip_cleanup_message_filter(); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_sip_register_service(&filter_module_tsx)) { | ||||
| 	if (internal_sip_register_service(&filter_module_tsx)) { | ||||
| 		ast_log(LOG_ERROR, "Could not register message filter module for incoming and outgoing requests\n"); | ||||
| 		ast_res_pjsip_cleanup_message_filter(); | ||||
| 		return -1; | ||||
|   | ||||
							
								
								
									
										121
									
								
								res/res_pjsip/pjsip_session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								res/res_pjsip/pjsip_session.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| /* | ||||
|  * Asterisk -- An open source telephony toolkit. | ||||
|  * | ||||
|  * Copyright (C) 2017, CFWare, LLC | ||||
|  * | ||||
|  * Corey Farrell <git@cfware.com> | ||||
|  * | ||||
|  * See http://www.asterisk.org for more information about | ||||
|  * the Asterisk project. Please do not directly contact | ||||
|  * any of the maintainers of this project for assistance; | ||||
|  * the project provides a web site, mailing lists and IRC | ||||
|  * channels for your use. | ||||
|  * | ||||
|  * This program is free software, distributed under the terms of | ||||
|  * the GNU General Public License Version 2. See the LICENSE file | ||||
|  * at the top of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "asterisk.h" | ||||
|  | ||||
| #include <pjsip.h> | ||||
| #include <pjsip_ua.h> | ||||
| #include <pjlib.h> | ||||
|  | ||||
| #include "asterisk/res_pjsip.h" | ||||
| #include "asterisk/res_pjsip_session.h" | ||||
| #include "include/res_pjsip_private.h" | ||||
| #include "asterisk/linkedlists.h" | ||||
| #include "asterisk/lock.h" | ||||
| #include "asterisk/module.h" | ||||
|  | ||||
|  | ||||
| AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement); | ||||
|  | ||||
| void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *iter; | ||||
| 	int inserted = 0; | ||||
| 	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); | ||||
|  | ||||
| 	if (!supplement->response_priority) { | ||||
| 		supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA; | ||||
| 	} | ||||
|  | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { | ||||
| 		if (iter->priority > supplement->priority) { | ||||
| 			AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next); | ||||
| 			inserted = 1; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_END; | ||||
|  | ||||
| 	if (!inserted) { | ||||
| 		AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) | ||||
| { | ||||
| 	internal_sip_session_register_supplement(supplement); | ||||
| 	internal_res_pjsip_ref(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *iter; | ||||
| 	int res = -1; | ||||
| 	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); | ||||
|  | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { | ||||
| 		if (supplement == iter) { | ||||
| 			AST_RWLIST_REMOVE_CURRENT(next); | ||||
| 			res = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_END; | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) | ||||
| { | ||||
| 	if (!internal_sip_session_unregister_supplement(supplement)) { | ||||
| 		internal_res_pjsip_unref(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst)); | ||||
|  | ||||
| 	if (!dst) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	/* Will need to revisit if shallow copy becomes an issue */ | ||||
| 	*dst = *src; | ||||
|  | ||||
| 	return dst; | ||||
| } | ||||
|  | ||||
| int ast_sip_session_add_supplements(struct ast_sip_session *session) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *iter; | ||||
| 	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK); | ||||
|  | ||||
| 	AST_RWLIST_TRAVERSE(&session_supplements, iter, next) { | ||||
| 		struct ast_sip_session_supplement *copy = supplement_dup(iter); | ||||
|  | ||||
| 		if (!copy) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 		AST_LIST_INSERT_TAIL(&session->supplements, copy, next); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -396,59 +396,6 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_ | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement); | ||||
|  | ||||
| int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *iter; | ||||
| 	int inserted = 0; | ||||
| 	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); | ||||
|  | ||||
| 	if (!supplement->response_priority) { | ||||
| 		supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA; | ||||
| 	} | ||||
|  | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { | ||||
| 		if (iter->priority > supplement->priority) { | ||||
| 			AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next); | ||||
| 			inserted = 1; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_END; | ||||
|  | ||||
| 	if (!inserted) { | ||||
| 		AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next); | ||||
| 	} | ||||
| 	ast_module_ref(ast_module_info->self); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *iter; | ||||
| 	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { | ||||
| 		if (supplement == iter) { | ||||
| 			AST_RWLIST_REMOVE_CURRENT(next); | ||||
| 			ast_module_unref(ast_module_info->self); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_END; | ||||
| } | ||||
|  | ||||
| static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst)); | ||||
| 	if (!dst) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	/* Will need to revisit if shallow copy becomes an issue */ | ||||
| 	*dst = *src; | ||||
| 	return dst; | ||||
| } | ||||
|  | ||||
| #define DATASTORE_BUCKETS 53 | ||||
| #define MEDIA_BUCKETS 7 | ||||
|  | ||||
| @@ -1380,21 +1327,6 @@ static void session_destructor(void *obj) | ||||
| 	ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name); | ||||
| } | ||||
|  | ||||
| static int add_supplements(struct ast_sip_session *session) | ||||
| { | ||||
| 	struct ast_sip_session_supplement *iter; | ||||
| 	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK); | ||||
|  | ||||
| 	AST_RWLIST_TRAVERSE(&session_supplements, iter, next) { | ||||
| 		struct ast_sip_session_supplement *copy = supplement_dup(iter); | ||||
| 		if (!copy) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 		AST_LIST_INSERT_TAIL(&session->supplements, copy, next); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int add_session_media(void *obj, void *arg, int flags) | ||||
| { | ||||
| 	struct sdp_handler_list *handler_list = obj; | ||||
| @@ -1523,7 +1455,7 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, | ||||
|  | ||||
| 	session->dtmf = endpoint->dtmf; | ||||
|  | ||||
| 	if (add_supplements(session)) { | ||||
| 	if (ast_sip_session_add_supplements(session)) { | ||||
| 		/* Release the ref held by session->inv_session */ | ||||
| 		ao2_ref(session, -1); | ||||
| 		return NULL; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user