[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