Fix race condition for CEL LINKEDID_END event

This patch fixes to situations that could cause the CEL LINKEDID_END event to
be missed.

1) During a core stop gracefully, modules are unloaded when ast_active_channels
== 0. The LINKDEDID_END event fires during the channel destructor. This means
that occasionally, the cel_* module will be unloaded before the channel is
destroyed. It seemed generally useful to wait until the refcount of all
channels == 0 before unloading, so I added a channel counter and used it in the
shutdown code.

2) During a masquerade, ast_channel_change_linkedid is called. It calls
ast_cel_check_retire_linkedid which unrefs the linkedid in the linkedids
container in cel.c. It didn't ref the new linkedid. Now it does. 

Review: https://reviewboard.asterisk.org/r/1900/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@367292 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Terry Wilson
2012-05-22 17:14:20 +00:00
parent c191395381
commit 9753325d32
5 changed files with 56 additions and 21 deletions

View File

@@ -1694,7 +1694,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart)
for (;;) {
time(&e);
/* Wait up to 15 seconds for all channels to go away */
if ((e - s) > 15 || !ast_active_channels() || shuttingdown != niceness) {
if ((e - s) > 15 || !ast_undestroyed_channels() || shuttingdown != niceness) {
break;
}
/* Sleep 1/10 of a second */
@@ -1708,7 +1708,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart)
ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
}
for (;;) {
if (!ast_active_channels() || shuttingdown != niceness) {
if (!ast_undestroyed_channels() || shuttingdown != niceness) {
break;
}
sleep(1);