[asterisk-commits] mmichelson: branch group/CCSS r238090 - in /team/group/CCSS: channels/ includ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 6 10:33:40 CST 2010


Author: mmichelson
Date: Wed Jan  6 10:33:36 2010
New Revision: 238090

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=238090
Log:
Use refcounting for agents instead of straight allocation.

The reason for this is that there are times where an entity needs
to get an ast_cc_agent structure. In order to do this, he must use
the ast_cc_agent_callback function to find the appropriate agent. The
problem is that since the agent is a component of the cc_core_instance
structure, and cc_core_instance is internal to ccss.c, it become impossible
to properly keep the refcount of the cc_core_instance correct.

The solution instead is to also keep a refcount of ast_cc_agents. This way,
when ast_cc_agent_callback is called, we can give a reference of the agent
to the caller while not having to worry about the refcount of the cc_core_instance.



Modified:
    team/group/CCSS/channels/chan_sip.c
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/chan_sip.c?view=diff&rev=238090&r1=238089&r2=238090
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Wed Jan  6 10:33:36 2010
@@ -12103,6 +12103,7 @@
 	 */
 	ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR");
 	add_header(resp, "Call-Info", ast_str_buffer(header));
+	ao2_ref(agent, -1);
 }
 
 /*! \brief Used for 200 OK and 183 early media
@@ -15458,6 +15459,7 @@
 			if (cc_recall_core_id) {
 				*cc_recall_core_id = agent->core_id;
 			}
+			ao2_ref(agent, -1);
 			return 0;
 		}
 	}
@@ -23895,6 +23897,7 @@
 
 	if (sip_pidf_validate(req, &pidf_doc) == FALSE) {
 		transmit_response(pvt, "400 Bad Request", req);
+		ao2_ref(agent, -1);
 		return -1;
 	}
 
@@ -23910,6 +23913,7 @@
 	if (!tuple_node) {
 		transmit_response(pvt, "400 Bad Request", req);
 		ast_xml_close(pidf_doc);
+		ao2_ref(agent, -1);
 		return -1;
 	}
 
@@ -23921,6 +23925,7 @@
 	if (!basic_node) {
 		transmit_response(pvt, "400 Bad Request", req);
 		ast_xml_close(pidf_doc);
+		ao2_ref(agent, -1);
 		return -1;
 	}
 
@@ -23930,6 +23935,7 @@
 		transmit_response(pvt, "400 Bad Request", req);
 		ast_xml_free_text(basic_status);
 		ast_xml_close(pidf_doc);
+		ao2_ref(agent, -1);
 		return -1;
 	}
 
@@ -23945,6 +23951,7 @@
 
 	ast_xml_free_text(basic_status);
 	ast_xml_close(pidf_doc);
+	ao2_ref(agent, -1);
 	return 0;
 }
 
@@ -24155,7 +24162,7 @@
 	/* We don't send a response here. That is done in the agent's ack callback or in the
 	 * agent destructor, should a failure occur before we have responded
 	 */
-
+	ao2_ref(agent, -1);
 	return 0;
 }
 

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=238090&r1=238089&r2=238090
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Wed Jan  6 10:33:36 2010
@@ -959,6 +959,10 @@
  * to anyone who has used ao2_callback. The final argument is the
  * type of agent you wish to have the callback called on.
  *
+ * \note Since agents are refcounted, and this function returns
+ * a reference to the agent, it is imperative that you decrement
+ * the refcount of the agent once you have finished using it.
+ *
  * \param flags astobj2 search flags
  * \param function an ao2 callback function to call
  * \param arg the argument to the callback function

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=238090&r1=238089&r2=238090
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Wed Jan  6 10:33:36 2010
@@ -266,7 +266,9 @@
 	struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
 	struct cc_core_instance *core_instance;
 	if ((core_instance = ao2_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper))) {
-		return core_instance->agent;
+		struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
+		cc_unref(core_instance, "agent callback done with the core_instance");
+		return agent;
 	}
 	return NULL;
 }
@@ -1820,13 +1822,21 @@
 	ast_assert(callbacks->destructor != NULL);
 }
 
+static void agent_destroy(void *data) {
+	struct ast_cc_agent *agent = data;
+	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);
+}
+
 static struct ast_cc_agent *cc_agent_init(struct ast_channel *caller_chan,
 		const char * const caller_name, const int core_id,
 		struct ast_cc_interface_tree *interface_tree)
 {
 	struct ast_cc_agent *agent;
 
-	if (!(agent = ast_calloc(1, sizeof(*agent) + strlen(caller_name)))) {
+	if (!(agent = ao2_alloc(sizeof(*agent) + strlen(caller_name), agent_destroy))) {
 		return NULL;
 	}
 
@@ -1850,14 +1860,6 @@
 	agent->interface_tree = cc_ref(interface_tree, "Agent now has reference to interface tree");
 	ast_log_dynamic_level(cc_logger_level, "Created an agent with core_id %d and caller %s\n", agent->core_id, agent->interface);
 	return agent;
-}
-
-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);
-	ast_free(agent);
 }
 
 /* Generic agent callbacks */
@@ -2141,7 +2143,7 @@
 		}
 		AST_LIST_UNLOCK(core_instance->agent->interface_tree);
 	}
-	agent_destroy(core_instance->agent);
+	cc_unref(core_instance->agent, "Core instance is done with the agent now\n");
 }
 
 static struct cc_core_instance *cc_core_init_instance(struct ast_channel *caller_chan,




More information about the asterisk-commits mailing list