[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