mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
DNS: Need to use the same serializer for a pjproject SIP transaction.
All send/receive processing for a SIP transaction needs to be done under the same threadpool serializer to prevent reentrancy problems inside pjproject when using an external DNS resolver to process messages for the transaction. * Add threadpool API call to get the current serializer associated with the worker thread. * Pick a serializer from a pool of default serializers if the caller of res_pjsip.c:ast_sip_push_task() does not provide one. This is a simple way to ensure that all outgoing SIP request messages are processed under a serializer. Otherwise, any place where a pushed task is done that would result in an outgoing out-of-dialog request would need to be modified to supply a serializer. Serializers from the default serializer pool are picked in a round robin sequence for simplicity. A side effect is that the default serializer pool will limit the growth of the thread pool from random tasks. This is not necessarily a bad thing. * Made pjsip_resolver.c use the requesting thread's serializer to execute the async callback. * Made pjsip_distributor.c save the thread's serializer name on the outgoing request tdata struct so the response can be processed under the same serializer. ASTERISK-25115 #close Reported by: John Bigelow Change-Id: Iea71c16ce1132017b5791635e198b8c27973f40a
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
#include "asterisk/dns_naptr.h"
|
||||
#include "asterisk/res_pjsip.h"
|
||||
#include "include/res_pjsip_private.h"
|
||||
#include "asterisk/taskprocessor.h"
|
||||
#include "asterisk/threadpool.h"
|
||||
|
||||
#ifdef HAVE_PJSIP_EXTERNAL_RESOLVER
|
||||
|
||||
@@ -52,6 +54,8 @@ struct sip_resolve {
|
||||
struct ast_dns_query_set *queries;
|
||||
/*! \brief Current viable server addresses */
|
||||
pjsip_server_addresses addresses;
|
||||
/*! \brief Serializer to run async callback into pjlib. */
|
||||
struct ast_taskprocessor *serializer;
|
||||
/*! \brief Callback to invoke upon completion */
|
||||
pjsip_resolver_callback *callback;
|
||||
/*! \brief User provided data */
|
||||
@@ -97,6 +101,7 @@ static void sip_resolve_destroy(void *data)
|
||||
|
||||
AST_VECTOR_FREE(&resolve->resolving);
|
||||
ao2_cleanup(resolve->queries);
|
||||
ast_taskprocessor_unreference(resolve->serializer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -398,7 +403,7 @@ static void sip_resolve_callback(const struct ast_dns_query_set *query_set)
|
||||
|
||||
/* Push a task to invoke the callback, we do this so it is guaranteed to run in a PJSIP thread */
|
||||
ao2_ref(resolve, +1);
|
||||
if (ast_sip_push_task(NULL, sip_resolve_invoke_user_callback, resolve)) {
|
||||
if (ast_sip_push_task(resolve->serializer, sip_resolve_invoke_user_callback, resolve)) {
|
||||
ao2_ref(resolve, -1);
|
||||
}
|
||||
|
||||
@@ -572,6 +577,8 @@ static void sip_resolve(pjsip_resolver_t *resolver, pj_pool_t *pool, const pjsip
|
||||
return;
|
||||
}
|
||||
|
||||
resolve->serializer = ao2_bump(ast_threadpool_serializer_get_current());
|
||||
|
||||
ast_debug(2, "[%p] Starting initial resolution using parallel queries for target '%s'\n", resolve, host);
|
||||
ast_dns_query_set_resolve_async(resolve->queries, sip_resolve_callback, resolve);
|
||||
|
||||
|
Reference in New Issue
Block a user