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
This commit is contained in:
Mark Michelson 2012-08-20 20:19:52 +00:00
parent a2068c3db6
commit db69da3667
1 changed files with 14 additions and 2 deletions

View File

@ -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 */