[svn-commits] rmudgett: branch rmudgett/bridge_phase r392307 - /team/rmudgett/bridge_phase/...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jun 19 21:58:20 CDT 2013


Author: rmudgett
Date: Wed Jun 19 21:58:19 2013
New Revision: 392307

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=392307
Log:
Handle the agent holding bridge being destroyed while in use.

Modified:
    team/rmudgett/bridge_phase/apps/app_agent_pool.c

Modified: team/rmudgett/bridge_phase/apps/app_agent_pool.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/apps/app_agent_pool.c?view=diff&rev=392307&r1=392306&r2=392307
==============================================================================
--- team/rmudgett/bridge_phase/apps/app_agent_pool.c (original)
+++ team/rmudgett/bridge_phase/apps/app_agent_pool.c Wed Jun 19 21:58:19 2013
@@ -878,8 +878,8 @@
 	return 0;
 }
 
-/*! Agent holding bridge instance. */
-static struct ast_bridge *agent_holding;
+/*! Agent holding bridge instance holder. */
+static AO2_GLOBAL_OBJ_STATIC(agent_holding);
 
 /*! Agent holding bridge deferred creation lock. */
 AST_MUTEX_DEFINE_STATIC(agent_holding_lock);
@@ -894,6 +894,7 @@
 
 static int bridge_agent_hold_disconnect(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 {
+	ast_softhangup(bridge_channel->chan, AST_SOFTHANGUP_EXPLICIT);
 	ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
 	return 0;
 }
@@ -1020,6 +1021,18 @@
 	bridge_channel->bridge_pvt = NULL;
 }
 
+/*!
+ * \brief Destroy the bridge.
+ *
+ * \param self Bridge to operate upon.
+ *
+ * \return Nothing
+ */
+static void bridge_agent_hold_destroy(struct ast_bridge *self)
+{
+	ao2_global_obj_replace_unref(agent_holding, NULL);
+}
+
 static struct ast_bridge_methods bridge_agent_hold_v_table;
 
 static struct ast_bridge *bridge_agent_hold_new(void)
@@ -1039,19 +1052,24 @@
 	/* Setup bridge agent_hold subclass v_table. */
 	bridge_agent_hold_v_table = ast_bridge_base_v_table;
 	bridge_agent_hold_v_table.name = "agent_hold";
+	bridge_agent_hold_v_table.destroy = bridge_agent_hold_destroy;
 	bridge_agent_hold_v_table.push = bridge_agent_hold_push;
 	bridge_agent_hold_v_table.pull = bridge_agent_hold_pull;
 }
 
 static int bridge_agent_hold_deferred_create(void)
 {
-	if (!agent_holding) {
+	RAII_VAR(struct ast_bridge *, holding, ao2_global_obj_ref(agent_holding), ao2_cleanup);
+
+	if (!holding) {
 		ast_mutex_lock(&agent_holding_lock);
-		if (!agent_holding) {
-			agent_holding = bridge_agent_hold_new();
+		holding = ao2_global_obj_ref(agent_holding);
+		if (!holding) {
+			holding = bridge_agent_hold_new();
+			ao2_global_obj_replace_unref(agent_holding, holding);
 		}
 		ast_mutex_unlock(&agent_holding_lock);
-		if (!agent_holding) {
+		if (!holding) {
 			ast_log(LOG_ERROR, "Could not create agent holding bridge.\n");
 			return -1;
 		}
@@ -1185,8 +1203,14 @@
 		for (;;) {
 			struct agents_cfg *cfgs;
 			struct agent_cfg *cfg;
-
-			ast_bridge_join(agent_holding, logged, NULL, &features, NULL, 0);
+			struct ast_bridge *holding;
+
+			holding = ao2_global_obj_ref(agent_holding);
+			if (!holding) {
+				break;
+			}
+
+			ast_bridge_join(holding, logged, NULL, &features, NULL, 1);
 			if (logged != agent->logged) {
 				/*
 				 * We are no longer the agent channel because of local channel
@@ -1850,6 +1874,8 @@
 
 static int unload_module(void)
 {
+	struct ast_bridge *holding;
+
 	/* Unregister dialplan applications */
 	ast_unregister_application(app_agent_login);
 	ast_unregister_application(app_agent_request);
@@ -1867,9 +1893,9 @@
 	ast_devstate_prov_del("Agent");
 
 	/* Destroy agent holding bridge. */
-	if (agent_holding) {
-		ast_bridge_destroy(agent_holding);
-		agent_holding = NULL;
+	holding = ao2_global_obj_replace(agent_holding, NULL);
+	if (holding) {
+		ast_bridge_destroy(holding);
 	}
 
 	destroy_config();




More information about the svn-commits mailing list