[svn-commits] file: branch file/bridging r90672 - /team/file/bridging/main/bridging.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Dec 3 15:37:02 CST 2007
Author: file
Date: Mon Dec 3 15:37:02 2007
New Revision: 90672
URL: http://svn.digium.com/view/asterisk?view=rev&rev=90672
Log:
Fix race condition with swapping. It was possible for the bridge thread to still be servicing the channel that was being swapped out while it was being handled elsewhere.
Modified:
team/file/bridging/main/bridging.c
Modified: team/file/bridging/main/bridging.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/bridging.c?view=diff&rev=90672&r1=90671&r2=90672
==============================================================================
--- team/file/bridging/main/bridging.c (original)
+++ team/file/bridging/main/bridging.c Mon Dec 3 15:37:02 2007
@@ -720,13 +720,23 @@
if ((swap_channel = find_bridge_channel(bridge, swap))) {
ast_debug(1, "Removing bridge channel %p from bridge %p and setting it to a swap state\n", swap_channel, bridge);
AST_LIST_REMOVE(&bridge->channels, swap_channel, list);
+ /* Signal the bridge thread to rebuild and poke it if required */
+ bridge->rebuild = 1;
+ if (bridge->thread != AST_PTHREADT_NULL)
+ pthread_kill(bridge->thread, SIGURG);
+ ast_debug(1, "Releasing bridge lock on %p to ensure swap operation from bridge thread\n", bridge);
+ ast_mutex_unlock(&bridge->lock);
+ usleep(1);
+ ast_mutex_lock(&bridge->lock);
+ ast_debug(1, "Reacquired bridge lock on %p\n", bridge);
ast_bridge_change_state(swap_channel, AST_BRIDGE_CHANNEL_STATE_SWAP);
bridge_channel.state = AST_BRIDGE_CHANNEL_STATE_SWAP;
/* We purposely unlock here to give time for the above to happen */
- ast_debug(1, "Releasing bridge lock on %p to ensure swap operation\n", bridge);
+ ast_debug(1, "Releasing bridge lock on %p to ensure swap operation from bridge channel thread\n", bridge);
ast_mutex_unlock(&bridge->lock);
usleep(1);
ast_mutex_lock(&bridge->lock);
+ ast_debug(1, "Reacquired bridge lock on %p\n", bridge);
}
}
@@ -818,15 +828,25 @@
if (swap) {
struct ast_bridge_channel *swap_channel = NULL;
if ((swap_channel = find_bridge_channel(bridge, swap))) {
- ast_debug(1, "Removing bridge channel %p from bridge %p and setting it to a swap state\n", swap_channel, bridge);
- AST_LIST_REMOVE(&bridge->channels, swap_channel, list);
- ast_bridge_change_state(swap_channel, AST_BRIDGE_CHANNEL_STATE_SWAP);
- bridge_channel->state = AST_BRIDGE_CHANNEL_STATE_SWAP;
- /* We purposely unlock here to give it time for the above to happen */
- ast_debug(1, "Releasing bridge lock on %p to ensure swap operation\n", bridge);
- ast_mutex_unlock(&bridge->lock);
- usleep(1);
- ast_mutex_lock(&bridge->lock);
+ ast_debug(1, "Removing bridge channel %p from bridge %p and setting it to a swap state\n", swap_channel, bridge);
+ AST_LIST_REMOVE(&bridge->channels, swap_channel, list);
+ /* Signal the bridge thread to rebuild and poke it if required */
+ bridge->rebuild = 1;
+ if (bridge->thread != AST_PTHREADT_NULL)
+ pthread_kill(bridge->thread, SIGURG);
+ ast_debug(1, "Releasing bridge lock on %p to ensure swap operation from bridge thread\n", bridge);
+ ast_mutex_unlock(&bridge->lock);
+ usleep(1);
+ ast_mutex_lock(&bridge->lock);
+ ast_debug(1, "Reacquired bridge lock on %p\n", bridge);
+ ast_bridge_change_state(swap_channel, AST_BRIDGE_CHANNEL_STATE_SWAP);
+ bridge_channel->state = AST_BRIDGE_CHANNEL_STATE_SWAP;
+ /* We purposely unlock here to give time for the above to happen */
+ ast_debug(1, "Releasing bridge lock on %p to ensure swap operation from bridge channel thread\n", bridge);
+ ast_mutex_unlock(&bridge->lock);
+ usleep(1);
+ ast_mutex_lock(&bridge->lock);
+ ast_debug(1, "Reacquired bridge lock on %p\n", bridge);
}
}
More information about the svn-commits
mailing list