diff options
author | Richard Mudgett <rmudgett@digium.com> | 2015-06-05 15:37:33 -0500 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2015-06-10 19:22:13 -0500 |
commit | 30cd559345853e3c057de10d3b21b577082a06c5 (patch) | |
tree | 617b6ab46a9d1f954daabd39fa1f674833e4e60b /main/threadpool.c | |
parent | b23f33e7e5bc1524d3e2b3536174590db575055e (diff) |
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
Diffstat (limited to 'main/threadpool.c')
-rw-r--r-- | main/threadpool.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/main/threadpool.c b/main/threadpool.c index 597e83e10..6b412d27f 100644 --- a/main/threadpool.c +++ b/main/threadpool.c @@ -1150,13 +1150,17 @@ static struct serializer *serializer_create(struct ast_threadpool *pool) return ser; } +AST_THREADSTORAGE_RAW(current_serializer); + static int execute_tasks(void *data) { struct ast_taskprocessor *tps = data; + ast_threadstorage_set_ptr(¤t_serializer, tps); while (ast_taskprocessor_execute(tps)) { /* No-op */ } + ast_threadstorage_set_ptr(¤t_serializer, NULL); ast_taskprocessor_unreference(tps); return 0; @@ -1192,6 +1196,11 @@ static struct ast_taskprocessor_listener_callbacks serializer_tps_listener_callb .shutdown = serializer_shutdown, }; +struct ast_taskprocessor *ast_threadpool_serializer_get_current(void) +{ + return ast_threadstorage_get_ptr(¤t_serializer); +} + struct ast_taskprocessor *ast_threadpool_serializer(const char *name, struct ast_threadpool *pool) { RAII_VAR(struct serializer *, ser, NULL, ao2_cleanup); |