[asterisk-commits] mmichelson: branch group/CCSS r220794 - in /team/group/CCSS: include/asterisk...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Sep 28 16:07:24 CDT 2009
Author: mmichelson
Date: Mon Sep 28 16:07:20 2009
New Revision: 220794
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=220794
Log:
Fix a race condition by introducing a new agent callback.
Modified:
team/group/CCSS/include/asterisk/ccss.h
team/group/CCSS/main/ccss.c
Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=220794&r1=220793&r2=220794
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Mon Sep 28 16:07:20 2009
@@ -660,6 +660,19 @@
*/
int (*start_offer_timer)(struct ast_cc_agent *agent);
/*!
+ * \brief Stop the offer timer
+ *
+ * The core will call this when the CC_CALLER_REQUESTED
+ * state has been reached. The duty of the agent here
+ * is to stop the configured offer timer.
+ *
+ * This callback is also called from the CC_COMPLETE and
+ * CC_FAILED states, so it is important that this callback
+ * accounts for the fact that it may be called even if there
+ * is no offer timer running on the agent.
+ */
+ int (*stop_offer_timer)(struct ast_cc_agent *agent);
+ /*!
* \brief Acknowledge CC request callback.
*
* The core will call this callback when
Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=220794&r1=220793&r2=220794
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Mon Sep 28 16:07:20 2009
@@ -100,6 +100,7 @@
/* Generic agent callbacks */
static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan);
static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent);
+static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent);
static void cc_generic_agent_ack(struct ast_cc_agent *agent);
static enum ast_device_state cc_generic_agent_status_request(struct ast_cc_agent *agent);
static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent);
@@ -111,6 +112,7 @@
.type = "generic",
.init = cc_generic_agent_init,
.start_offer_timer = cc_generic_agent_start_offer_timer,
+ .stop_offer_timer = cc_generic_agent_stop_offer_timer,
.ack = cc_generic_agent_ack,
.status_request = cc_generic_agent_status_request,
.start_monitoring = cc_generic_agent_start_monitoring,
@@ -562,6 +564,7 @@
{
ast_assert(callbacks->init != NULL);
ast_assert(callbacks->start_offer_timer != NULL);
+ ast_assert(callbacks->stop_offer_timer != NULL);
ast_assert(callbacks->ack != NULL);
ast_assert(callbacks->status_request != NULL);
ast_assert(callbacks->start_monitoring != NULL);
@@ -639,6 +642,7 @@
}
static void agent_destroy(struct ast_cc_agent *agent) {
+ agent->callbacks->stop_offer_timer(agent);
agent->callbacks->destructor(agent);
agent->interface_tree = cc_unref(agent->interface_tree, "Destroying agent, removing ref to interface tree");
ast_cc_config_params_destroy(agent->cc_params);
@@ -749,6 +753,17 @@
return -1;
}
generic_pvt->offer_timer_id = sched_id;
+ return 0;
+}
+
+static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent)
+{
+ struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
+
+ if (generic_pvt->offer_timer_id != -1) {
+ ast_sched_thread_del(cc_sched_thread, generic_pvt->offer_timer_id);
+ generic_pvt->offer_timer_id = -1;
+ }
return 0;
}
@@ -868,10 +883,6 @@
if (agent_pvt->sub) {
agent_pvt->sub = ast_event_unsubscribe(agent_pvt->sub);
- }
-
- if (agent_pvt->offer_timer_id != -1) {
- ast_sched_thread_del(cc_sched_thread, agent_pvt->offer_timer_id);
}
ast_free(agent_pvt);
@@ -1221,6 +1232,7 @@
ast_log(LOG_NOTICE, "Invalid state change request. Cannot go from %d to %d\n", core_instance->current_state, args->state);
}
core_instance->current_state = args->state;
+ core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
cc_monitor_tree_init(args->core_id);
/* It doesn't matter what service we state for the root monitor, so we just use AST_CC_NONE */
core_instance->monitor->callbacks->request_cc(core_instance->monitor, core_instance->core_id, NULL);
@@ -1327,7 +1339,6 @@
{
struct cc_core_instance *core_instance;
char interface[AST_CHANNEL_NAME];
- struct cc_generic_agent_pvt *generic_pvt;
char *dash;
unsigned long match_flags;
int res;
@@ -1351,15 +1362,6 @@
return -1;
}
- generic_pvt = core_instance->agent->private_data;
-
- /* Generic agents have the flexibility of requesting CC either while
- * still on the failed call, or after hanging up. As such, the offer timer
- * is not always guaranteed to be running when the caller makes his request.
- */
- if (generic_pvt->offer_timer_id != -1) {
- ast_sched_thread_del(cc_sched_thread, generic_pvt->offer_timer_id);
- }
res = ast_cc_request_state_change(CC_CALLER_REQUESTED, core_instance->core_id, "CallCompletionRequest called");
cc_unref(core_instance, "Done with CallCompletionRequest");
return res;
More information about the asterisk-commits
mailing list