diff options
author | Richard Mudgett <rmudgett@digium.com> | 2015-01-28 04:29:23 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2015-01-28 04:29:23 +0000 |
commit | 69e107b24eb15499b7ad8fe03a9368ea55680a8b (patch) | |
tree | 2291bcac20d4077076c49533db44f45bc2d3245e /res/res_pjsip.c | |
parent | c7591ef6bc6ad4c4e1c7f6a66de78b6ff70dc913 (diff) |
res_pjsip_outbound_registration: Fix reload race condition.
Performing a CLI "module reload" command when there are new pjsip.conf
registration objects defined frequently failed to load them correctly.
What happens is a race condition between res_pjsip pushing its reload into
an asynchronous task processor task and the thread that does the rest of
the reloads when it gets to reloading the res_pjsip_outbound_registration
module. A similar race condition happens between a reload and the CLI/AMI
show registrations commands. The reload updates the current_states
container and the CLI/AMI commands call get_registrations() which builds a
new current_states container.
* Made res_pjsip.c reload_module() use ast_sip_push_task_synchronous()
instead of ast_sip_push_task() to eliminate two threads processing config
reloads at the same time.
* Made get_registrations() not replace the global current_states container
so the CLI/AMI show registrations command cannot interfere with reloading.
You could never add/remove objects in the container without the
possibility of the container being replaced out from under you by
get_registrations().
* Added a registration loaded sorcery instance observer to purge any dead
registration objects since get_registrations() cannot do this job anymore.
The struct ast_sorcery_instance_observer callbacks must be used because
the callback happens inline with the load process. The struct
ast_sorcery_observer callbacks are pushed to a different thread.
* Added some global current_states NULL pointer checks in case the
container disappears because of unload_module().
* Made sorcery's struct ast_sorcery_instance_observer.object_type_loaded
callbacks guaranteed to be called before any struct
ast_sorcery_observer.loaded callbacks will be called.
* Moved the check for non-reloadable objects to before the sorcery
instance loading callbacks happen to short circuit unnecessary work.
Previously with non-reloadable objects, the sorcery instance
loading/loaded callbacks would always happen, the individual wizard
loading/loaded would be prevented, and the non-reloadable type logging
message would be logged for each associated wizard.
ASTERISK-24729 #close
Review: https://reviewboard.asterisk.org/r/4381/
........
Merged revisions 431243 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@431251 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip.c')
-rw-r--r-- | res/res_pjsip.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c index b2b7d6358..149a2d8be 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -3316,7 +3316,11 @@ static int load_module(void) static int reload_module(void) { - if (ast_sip_push_task(NULL, reload_configuration_task, NULL)) { + /* + * We must wait for the reload to complete so multiple + * reloads cannot happen at the same time. + */ + if (ast_sip_push_task_synchronous(NULL, reload_configuration_task, NULL)) { ast_log(LOG_WARNING, "Failed to reload PJSIP\n"); return -1; } |