[svn-commits] rmudgett: branch rmudgett/bridge_phase r393307 - in /team/rmudgett/bridge_pha...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jul 1 10:36:08 CDT 2013


Author: rmudgett
Date: Mon Jul  1 10:36:05 2013
New Revision: 393307

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=393307
Log:
Revert after bridge callback failed callback prototype.

Modified:
    team/rmudgett/bridge_phase/apps/app_agent_pool.c
    team/rmudgett/bridge_phase/include/asterisk/bridging.h
    team/rmudgett/bridge_phase/main/bridging.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=393307&r1=393306&r2=393307
==============================================================================
--- team/rmudgett/bridge_phase/apps/app_agent_pool.c (original)
+++ team/rmudgett/bridge_phase/apps/app_agent_pool.c Mon Jul  1 10:36:05 2013
@@ -1057,9 +1057,8 @@
 	return 0;
 }
 
-static void agent_logout(struct agent_pvt *agent);
 static void agent_after_bridge_cb(struct ast_channel *chan, void *data);
-static void agent_after_bridge_cb_failed(struct ast_channel *chan, void *data, enum ast_after_bridge_cb_reason reason);
+static void agent_after_bridge_cb_failed(enum ast_after_bridge_cb_reason reason, void *data);
 
 /*!
  * \internal
@@ -1136,6 +1135,13 @@
 	}
 
 	if (swap) {
+		res = ast_after_bridge_callback_set(chan, agent_after_bridge_cb,
+			agent_after_bridge_cb_failed, chan);
+		if (res) {
+			ast_channel_remove_bridge_role(chan, "holding_participant");
+			return -1;
+		}
+
 		agent_lock(agent);
 		ast_channel_unref(agent->logged);
 		agent->logged = ast_channel_ref(chan);
@@ -1148,25 +1154,22 @@
 		 * cases.
 		 */
 		ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
-
-/* BUGBUG this failure condition as well as other threads potentially trying to add their own after bridge callbacks has issues. */
-		ao2_ref(agent, +1);
-		res = ast_after_bridge_callback_set(chan, agent_after_bridge_cb,
-			agent_after_bridge_cb_failed, agent);
-		if (res) {
-			ao2_ref(agent, -1);
-			agent_lock(agent);
-			agent_logout(agent);
-			ast_channel_remove_bridge_role(chan, "holding_participant");
-			return -1;
-		}
 		return 0;
 	}
 
 	agent_lock(agent);
 	switch (agent->state) {
 	case AGENT_STATE_LOGGED_OUT:
-		/* Start the login probation timer.*/
+		/*
+		 * Start the login probation timer.
+		 *
+		 * We cannot handle an agent local channel optimization when the
+		 * agent is on a call.  The optimization may kick the agent
+		 * channel we know about out of the call without our being able
+		 * to switch to the replacement channel.  Get any agent local
+		 * channel optimization out of the way while the agent is in the
+		 * holding bridge.
+		 */
 		time(&agent->probation_start);
 		agent->state = AGENT_STATE_PROBATION_WAIT;
 		agent_unlock(agent);
@@ -1511,7 +1514,12 @@
 
 static void agent_after_bridge_cb(struct ast_channel *chan, void *data)
 {
-	struct agent_pvt *agent = data;
+	struct agent_pvt *agent;
+
+	agent = ao2_find(agents, chan, 0);
+	if (!agent) {
+		return;
+	}
 
 	ast_debug(1, "Agent %s: New agent channel %s.\n",
 		agent->username, ast_channel_name(chan));
@@ -1533,39 +1541,21 @@
  * The failed callback will always run in a known thread
  * context.  A big plus.
  */
-static void agent_after_bridge_cb_failed(struct ast_channel *chan, void *data, enum ast_after_bridge_cb_reason reason)
-{
-	struct ast_bridge *holding;
-	struct ast_channel *logged;
-	RAII_VAR(struct agent_pvt *, agent, data, ao2_cleanup);
-
-	ast_assert(chan != NULL);
-
-	agent_lock(agent);
-	if (chan != agent->logged) {
-		/*
-		 * We are no longer the agent channel because of local channel
-		 * optimization.
-		 */
-		agent_unlock(agent);
-		ast_debug(1, "Agent %s: Channel %s is no longer the agent.\n",
-			agent->username, ast_channel_name(chan));
+static void agent_after_bridge_cb_failed(enum ast_after_bridge_cb_reason reason, void *data)
+{
+	struct ast_channel *chan = data;
+	struct agent_pvt *agent;
+
+	agent = ao2_find(agents, chan, 0);
+	if (!agent) {
 		return;
 	}
-	logged = ast_channel_ref(agent->logged);
 	ast_log(LOG_WARNING, "Agent %s: Forced logout.  Lost control of %s because: %s\n",
 		agent->username, ast_channel_name(chan),
 		ast_after_bridge_cb_reason_string(reason));
+	agent_lock(agent);
 	agent_logout(agent);
-
-	holding = ao2_global_obj_ref(agent_holding);
-	if (!holding) {
-		ast_channel_unref(logged);
-		return;
-	}
-	ast_bridge_remove(holding, logged);
-	ao2_ref(holding, -1);
-	ast_channel_unref(logged);
+	ao2_ref(agent, -1);
 }
 
 /*!

Modified: team/rmudgett/bridge_phase/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridging.h?view=diff&rev=393307&r1=393306&r2=393307
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridging.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridging.h Mon Jul  1 10:36:05 2013
@@ -1663,13 +1663,12 @@
  * \brief After bridge callback failed.
  * \since 12.0.0
  *
- * \param chan Channel failing the callback.
+ * \param reason Reason callback is failing.
  * \param data Extra data what setup the callback wanted to pass.
- * \param reason Reason callback is failing.
- *
- * \return Nothing
- */
-typedef void (*ast_after_bridge_cb_failed)(struct ast_channel *chan, void *data, enum ast_after_bridge_cb_reason reason);
+ *
+ * \return Nothing
+ */
+typedef void (*ast_after_bridge_cb_failed)(enum ast_after_bridge_cb_reason reason, void *data);
 
 /*!
  * \brief After bridge callback function.

Modified: team/rmudgett/bridge_phase/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/bridging.c?view=diff&rev=393307&r1=393306&r2=393307
==============================================================================
--- team/rmudgett/bridge_phase/main/bridging.c (original)
+++ team/rmudgett/bridge_phase/main/bridging.c Mon Jul  1 10:36:05 2013
@@ -2548,7 +2548,7 @@
 	}
 }
 
-static void after_bridge_move_channel_fail(struct ast_channel *chan_bridged, void *data, enum ast_after_bridge_cb_reason reason)
+static void after_bridge_move_channel_fail(enum ast_after_bridge_cb_reason reason, void *data)
 {
 	RAII_VAR(struct ast_channel *, chan_target, data, ao2_cleanup);
 
@@ -3167,11 +3167,8 @@
 {
 	struct after_bridge_cb_ds *after_bridge = data;
 
-	/* The datastore should never be destroyed with a failed callback still active. */
-	ast_assert(after_bridge->failed == NULL);
-
 	if (after_bridge->failed) {
-		after_bridge->failed(NULL, after_bridge->data, AST_AFTER_BRIDGE_CB_REASON_DESTROY);
+		after_bridge->failed(AST_AFTER_BRIDGE_CB_REASON_DESTROY, after_bridge->data);
 		after_bridge->failed = NULL;
 	}
 	ast_free(after_bridge);
@@ -3236,7 +3233,7 @@
 		struct after_bridge_cb_ds *after_bridge = old_datastore->data;
 
 		if (after_bridge->failed) {
-			after_bridge->failed(chan, after_bridge->data, reason);
+			after_bridge->failed(reason, after_bridge->data);
 			after_bridge->failed = NULL;
 		}
 		ast_datastore_free(old_datastore);




More information about the svn-commits mailing list