[asterisk-commits] file: branch file/bridging r90672 - /team/file/bridging/main/bridging.c

SVN commits to the Asterisk project asterisk-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 asterisk-commits mailing list