[asterisk-commits] mmichelson: branch group/CCSS r220173 - /team/group/CCSS/main/ccss.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 24 11:30:17 CDT 2009


Author: mmichelson
Date: Thu Sep 24 11:30:14 2009
New Revision: 220173

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=220173
Log:
Initial work towards properly destroying agents.

* Added agent_destroy, which will call a technology's destructor
* offer timeout expire now correctly sets the offer timer id to -1
* Fixed an occurrence where an ast_cc_interface was not ao2_alloced.
* Fixed a spot in generic_recall where if the callback macro failed to
  execute properly, we would not shut down the CC state machine properly.

At this point, I'm seeing some oddball SIP behavior. I will svn update
and see if I can pinpoint the problem.


Modified:
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=220173&r1=220172&r2=220173
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Thu Sep 24 11:30:14 2009
@@ -711,7 +711,9 @@
 static int offer_timer_expire(const void *data)
 {
 	const struct ast_cc_agent *agent = data;
+	struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
 	ast_log(LOG_NOTICE, "Queuing change request because offer timer has expired.\n");
+	agent_pvt->offer_timer_id = -1;
 	ast_cc_request_state_change(CC_FAILED, agent->core_id, "Generic agent offer timer expired");
 	return 0;
 }
@@ -810,7 +812,10 @@
 	}
 	if (!ast_strlen_zero(callback_macro)) {
 		ast_log(LOG_NOTICE, "There's a callback macro configured\n");
-		ast_app_run_macro(NULL, chan, callback_macro, NULL);
+		if (ast_app_run_macro(NULL, chan, callback_macro, NULL)) {
+			ast_cc_request_state_change(CC_FAILED, agent->core_id, "Callback macro failed. Maybe a hangup?");
+			return NULL;
+		}
 	}
 	/* We have a channel. It's time now to set up the datastore of recalled CC interfaces.
 	 * This will be a common task for all recall functions. If it were possible, I'd have
@@ -849,11 +854,17 @@
 		agent_pvt->sub = ast_event_unsubscribe(agent_pvt->sub);
 	}
 
-	ast_sched_thread_del(cc_sched_thread, agent_pvt->offer_timer_id);
-
-	agent->interface_tree = cc_unref(agent->interface_tree, "Agent destructor");
+	if (agent_pvt->offer_timer_id != -1) {
+		ast_sched_thread_del(cc_sched_thread, agent_pvt->offer_timer_id);
+	}
 
 	ast_free(agent_pvt);
+}
+
+static void agent_destroy(struct ast_cc_agent *agent) {
+	agent->interface_tree = cc_unref(agent->interface_tree, "Destroying agent, removing ref to interface tree");
+	agent->callbacks->destructor(agent);
+	ast_free(agent);
 }
 
 static const struct ast_cc_monitor_callbacks *find_monitor_callbacks(const char * const type)
@@ -1259,11 +1270,13 @@
 			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;
+		agent_destroy(core_instance->agent);
 		prune_links(core_instance->monitor, core_instance->core_id, NULL);
 		break;
 	case CC_FAILED:
 		/* Something along the way failed, call agent and monitor destructor functions
 		 */
+		agent_destroy(core_instance->agent);
 		if (core_instance->monitor) {
 			prune_links(core_instance->monitor, core_instance->core_id, NULL);
 		}
@@ -1898,7 +1911,7 @@
 
 static struct ast_cc_interface *root_interface_init(void)
 {
-	struct ast_cc_interface *cc_interface = ast_calloc(1, sizeof(*cc_interface) + strlen("root"));
+	struct ast_cc_interface *cc_interface = ao2_alloc(sizeof(*cc_interface) + strlen("root"), ast_cc_interface_destroy);
 
 	strcpy(cc_interface->name, "root");
 	cc_interface->monitor_class = AST_CC_ROOT_MONITOR;




More information about the asterisk-commits mailing list