mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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
This commit is contained in:
@@ -144,8 +144,6 @@ struct ast_bridge_channel {
|
|||||||
AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue;
|
AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue;
|
||||||
/*! Pipe to alert thread when frames are put into the wr_queue. */
|
/*! Pipe to alert thread when frames are put into the wr_queue. */
|
||||||
int alert_pipe[2];
|
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.
|
* \brief The bridge channel thread activity.
|
||||||
*
|
*
|
||||||
|
@@ -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)
|
static void bridge_channel_poke(struct ast_bridge_channel *bridge_channel)
|
||||||
{
|
{
|
||||||
if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
|
if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
|
||||||
while (bridge_channel->waiting) {
|
/* Wake up the bridge channel thread. */
|
||||||
pthread_kill(bridge_channel->thread, SIGURG);
|
ast_queue_frame(bridge_channel->chan, &ast_null_frame);
|
||||||
sched_yield();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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",
|
ast_debug(10, "Bridge %s: %p(%s) is going into a waitfor\n",
|
||||||
bridge_channel->bridge->uniqueid, bridge_channel,
|
bridge_channel->bridge->uniqueid, bridge_channel,
|
||||||
ast_channel_name(bridge_channel->chan));
|
ast_channel_name(bridge_channel->chan));
|
||||||
bridge_channel->waiting = 1;
|
|
||||||
ast_bridge_channel_unlock(bridge_channel);
|
ast_bridge_channel_unlock(bridge_channel);
|
||||||
outfd = -1;
|
outfd = -1;
|
||||||
ms = bridge_channel_next_interval(bridge_channel);
|
ms = bridge_channel_next_interval(bridge_channel);
|
||||||
chan = ast_waitfor_nandfds(&bridge_channel->chan, 1,
|
chan = ast_waitfor_nandfds(&bridge_channel->chan, 1,
|
||||||
&bridge_channel->alert_pipe[0], 1, NULL, &outfd, &ms);
|
&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) {
|
if (ast_channel_softhangup_internal_flag(bridge_channel->chan) & AST_SOFTHANGUP_UNBRIDGE) {
|
||||||
ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE);
|
ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE);
|
||||||
ast_bridge_channel_lock_bridge(bridge_channel);
|
ast_bridge_channel_lock_bridge(bridge_channel);
|
||||||
|
Reference in New Issue
Block a user