[asterisk-commits] russell: branch 1.8 r354492 - /branches/1.8/main/channel.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 8 20:23:57 CST 2012
Author: russell
Date: Wed Feb 8 20:23:53 2012
New Revision: 354492
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=354492
Log:
Remove some unnecessary locking from ast_hangup().
This patch removes some unnecessary locking of the channels container in
ast_hangup(). The reason this came up is that this lock can very quickly block
the entire system. If any of the channel cleanup code decides to block, it
causes a problem for the whole system. For example, when audiohooks get
destroyed, if that blocks for a while waiting on the mixmonitor thread to exit
because it's busy blocking on some I/O, it causes a problem for many other
threads in the meantime.
Review: https://reviewboard.asterisk.org/r/1712/
Modified:
branches/1.8/main/channel.c
Modified: branches/1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/channel.c?view=diff&rev=354492&r1=354491&r2=354492
==============================================================================
--- branches/1.8/main/channel.c (original)
+++ branches/1.8/main/channel.c Wed Feb 8 20:23:53 2012
@@ -2729,21 +2729,25 @@
}
}
-/*! \brief Hangup a channel */
-int ast_hangup(struct ast_channel *chan)
-{
- char extra_str[64]; /* used for cel logging below */
-
- ast_autoservice_stop(chan);
-
- ao2_lock(channels);
- ast_channel_lock(chan);
-
+static void destroy_hooks(struct ast_channel *chan)
+{
if (chan->audiohooks) {
ast_audiohook_detach_list(chan->audiohooks);
chan->audiohooks = NULL;
}
+
ast_framehook_list_destroy(chan);
+}
+
+/*! \brief Hangup a channel */
+int ast_hangup(struct ast_channel *chan)
+{
+ char extra_str[64]; /* used for cel logging below */
+ int was_zombie;
+
+ ast_autoservice_stop(chan);
+
+ ast_channel_lock(chan);
/*
* Do the masquerade if someone is setup to masquerade into us.
@@ -2755,16 +2759,13 @@
*/
while (chan->masq) {
ast_channel_unlock(chan);
- ao2_unlock(channels);
if (ast_do_masquerade(chan)) {
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
/* Abort the loop or we might never leave. */
- ao2_lock(channels);
ast_channel_lock(chan);
break;
}
- ao2_lock(channels);
ast_channel_lock(chan);
}
@@ -2775,13 +2776,20 @@
* to free it later.
*/
ast_set_flag(chan, AST_FLAG_ZOMBIE);
+ destroy_hooks(chan);
ast_channel_unlock(chan);
- ao2_unlock(channels);
return 0;
}
+ if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) {
+ ast_set_flag(chan, AST_FLAG_ZOMBIE);
+ }
+
+ ast_channel_unlock(chan);
ao2_unlink(channels, chan);
- ao2_unlock(channels);
+ ast_channel_lock(chan);
+
+ destroy_hooks(chan);
free_translation(chan);
/* Close audio stream */
@@ -2816,14 +2824,9 @@
(long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
}
- if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
+ if (!was_zombie) {
ast_debug(1, "Hanging up channel '%s'\n", chan->name);
- /*
- * This channel is now dead so mark it as a zombie so anyone
- * left holding a reference to this channel will not use it.
- */
- ast_set_flag(chan, AST_FLAG_ZOMBIE);
if (chan->tech->hangup) {
chan->tech->hangup(chan);
}
More information about the asterisk-commits
mailing list