From db69da3667955373c06ebae66141c3cd42834fcc Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Mon, 20 Aug 2012 20:19:52 +0000 Subject: Use thread-local storage to store pj_thread_descs. pj_thread_register() takes a parameter of type pj_thread_desc. It was assumed that pj_thread_register either used this item temporarily or made a copy of it. Unfortunately, all it does is keep a pointer to the structure in thread-local storage. This means that if our pj_thread_desc goes out of scope, then pjlib will be referencing bogus data quite often, most commonly on operations involving a pj_mutex_t. In our case, our pj_thread_desc was on the stack and went out of scope very shortly after registering our thread with pjlib. With this change, the pj_thread_desc is stored in thread-local storage so the pointer that pjlib keeps in thread-local storage will reference legitimate memory. (closes issue ASTERISK-20237) reported by Jeremy Pepper Patches: ASTERISK-20237.patch uploaded by Mark Michelson (license #5049) Tested by Jeremy Pepper ........ Merged revisions 371571 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@371572 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/res_rtp_asterisk.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'res/res_rtp_asterisk.c') diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 6892b1878..aa7895bb2 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -416,17 +416,29 @@ static void ast_rtp_ice_add_remote_candidate(struct ast_rtp_instance *instance, ao2_ref(remote_candidate, -1); } +AST_THREADSTORAGE(pj_thread_storage); + /*! \brief Function used to check if the calling thread is registered with pjlib. If it is not it will be registered. */ static void pj_thread_register_check(void) { - pj_thread_desc desc; + pj_thread_desc *desc; pj_thread_t *thread; if (pj_thread_is_registered() == PJ_TRUE) { return; } - pj_thread_register("Asterisk Thread", desc, &thread); + desc = ast_threadstorage_get(&pj_thread_storage, sizeof(pj_thread_desc)); + if (!desc) { + ast_log(LOG_ERROR, "Could not get thread desc from thread-local storage. Expect awful things to occur\n"); + return; + } + pj_bzero(*desc, sizeof(*desc)); + + if (pj_thread_register("Asterisk Thread", *desc, &thread) != PJ_SUCCESS) { + ast_log(LOG_ERROR, "Coudln't register thread with PJLIB.\n"); + } + return; } /*! \brief Helper function which updates an ast_sockaddr with the candidate used for the component */ -- cgit v1.2.3