[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