From d647b4ae022cbce0aaee03e8ba51de013ed0ae80 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Mon, 26 Aug 2013 16:25:39 +0000 Subject: bridging: Fix a livelock with local channel optimization. Use a better means of waking up the bridge channel thread. ........ Merged revisions 397650 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397651 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/bridge_channel.h | 2 -- main/bridge_channel.c | 8 ++------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/include/asterisk/bridge_channel.h b/include/asterisk/bridge_channel.h index 149c8e0d1..de67347bb 100644 --- a/include/asterisk/bridge_channel.h +++ b/include/asterisk/bridge_channel.h @@ -144,8 +144,6 @@ struct ast_bridge_channel { AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue; /*! Pipe to alert thread when frames are put into the wr_queue. */ int alert_pipe[2]; - /*! TRUE if the bridge channel thread is waiting on channels (needs to be atomically settable) */ - int waiting; /*! * \brief The bridge channel thread activity. * diff --git a/main/bridge_channel.c b/main/bridge_channel.c index 9de612ea6..92ad660ea 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -110,10 +110,8 @@ int ast_bridge_channel_notify_talking(struct ast_bridge_channel *bridge_channel, static void bridge_channel_poke(struct ast_bridge_channel *bridge_channel) { if (!pthread_equal(pthread_self(), bridge_channel->thread)) { - while (bridge_channel->waiting) { - pthread_kill(bridge_channel->thread, SIGURG); - sched_yield(); - } + /* Wake up the bridge channel thread. */ + ast_queue_frame(bridge_channel->chan, &ast_null_frame); } } @@ -1883,13 +1881,11 @@ static void bridge_channel_wait(struct ast_bridge_channel *bridge_channel) ast_debug(10, "Bridge %s: %p(%s) is going into a waitfor\n", bridge_channel->bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan)); - bridge_channel->waiting = 1; ast_bridge_channel_unlock(bridge_channel); outfd = -1; ms = bridge_channel_next_interval(bridge_channel); chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, &bridge_channel->alert_pipe[0], 1, NULL, &outfd, &ms); - bridge_channel->waiting = 0; if (ast_channel_softhangup_internal_flag(bridge_channel->chan) & AST_SOFTHANGUP_UNBRIDGE) { ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE); ast_bridge_channel_lock_bridge(bridge_channel); -- cgit v1.2.3