[svn-commits] mmichelson: branch group/CCSS r215644 - in /team/group/CCSS: include/asterisk...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed Sep 2 15:46:10 CDT 2009
Author: mmichelson
Date: Wed Sep 2 15:46:07 2009
New Revision: 215644
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=215644
Log:
Checking in progress with monitor creation.
Most of what's necessary is in place, but lord does
it need lots and lots and lots of tweaking. One
big thing I need to do next is to make sure that
the frame data in the AST_CONTROL_CC frame has
all that is necessary so that the ensuing
ast_cc_interface has the information so that the
monitor can then have the information.
I think I'll write a specialized frame queuing
function for the frame type.
Modified:
team/group/CCSS/include/asterisk/ccss.h
team/group/CCSS/main/ccss.c
Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=215644&r1=215643&r2=215644
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Wed Sep 2 15:46:07 2009
@@ -386,6 +386,9 @@
* representing dialplan extensions.
*/
enum ast_cc_service_type service_offered;
+ /* What class of monitor is being offered here
+ */
+ enum ast_cc_monitor_class monitor_class;
/*!
* The type of monitor that should be used for this interface
*
@@ -450,7 +453,7 @@
* of monitor an ast_cc_device_monitor
* is.
*/
-enum ast_cc_monitor_type {
+enum ast_cc_monitor_class {
AST_CC_DEVICE_MONITOR,
AST_CC_EXTENSION_MONITOR,
/* A root monitor is a placeholder type, which serves
@@ -473,7 +476,7 @@
*/
struct ast_cc_monitor {
/*! One of CCBS or CCNR. */
- enum ast_cc_monitor_type type;
+ enum ast_cc_monitor_class monitor_class;
/*! The list of links to upstream extension monitors */
AST_LIST_HEAD(,ast_cc_monitor_link) parent_links;
AST_LIST_HEAD(,ast_cc_monitor_link) child_links;
Modified: team/group/CCSS/main/ccss.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=215644&r1=215643&r2=215644
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Wed Sep 2 15:46:07 2009
@@ -436,9 +436,32 @@
struct ao2_container *pending_cc_offers;
struct ao2_container *cc_core_instances;
+struct ao2_container *cc_monitors;
static const int CC_PENDING_OFFER_BUCKETS = 53;
static const int CC_CORE_INSTANCES_BUCKETS = 17;
+
+static int cc_monitor_cmp_fn(void *obj, void *arg, int flags)
+{
+ struct ast_cc_monitor *monitor1 = obj;
+ struct ast_cc_monitor *monitor2 = arg;
+
+ if (!strcmp(monitor1->name, monitor2->name) &&
+ !strcmp(monitor1->monitor_type, monitor2->monitor_type)) {
+ return CMP_MATCH | CMP_STOP;
+ }
+ return 0;
+}
+
+static int cc_monitor_hash_fn(void *obj, int flags)
+{
+ struct ast_cc_monitor *monitor = obj;
+ /* I have no idea if adding the two hashes together
+ * like this increases the odds of hash collisions or
+ * not.
+ */
+ return ast_str_hash(monitor->monitor_type) + ast_str_hash(monitor->name);
+}
/*!
* \brief Struct for CC offers, before a monitor is created
@@ -785,7 +808,8 @@
return callbacks;
}
-static struct ast_cc_monitor *cc_monitor_instance_init(enum ast_cc_monitor_type type, const char * const callback_type, const char * const monitor_name, const int core_id)
+static struct ast_cc_monitor *cc_monitor_instance_init(enum ast_cc_monitor_class monitor_class,
+ const char * const callback_type, const char * const monitor_name, const int core_id)
{
struct ast_cc_monitor *monitor;
const struct ast_cc_monitor_callbacks *callbacks = find_monitor_callbacks(callback_type);
@@ -796,11 +820,50 @@
return NULL;
}
- monitor->type = type;
+ monitor->monitor_class = monitor_class;
strcpy(monitor->name, monitor_name);
monitor->callbacks = callbacks;
monitor->callbacks->init(monitor, core_id);
+ AST_LIST_HEAD_INIT(monitor->child_links);
+ AST_LIST_HEAD_INIT(monitor->parent_links);
+ ao2_link(cc_monitors, monitor);
return monitor;
+}
+
+static ast_cc_monitor *find_or_create_monitor(struct ast_cc_monitor *parent, struct ast_cc_interface *interface)
+{
+ /* I'll leave the finding part for later. For now, I'll place the
+ * creation code here
+ */
+ struct ast_cc_monitor *new_monitor;
+ struct ast_cc_monitor_link *new_link;
+ struct ast_cc_monitor finder = alloca(sizeof(finder) + strlen(interface->name));
+ int monitor_created = 1;
+
+ strcpy(finder->name, interface->name);
+ finder->monitor_class = interface->monitor_class;
+
+ if ((new_monitor = ao2_find(cc_monitors, &finder, OBJ_POINTER))) {
+ monitor_created = 0;
+ } else if (!(new_monitor = cc_monitor_instance_init(interface->monitor_class,
+ interface->monitor_type, interface->name, core_id))) {
+ return NULL;
+ }
+
+ if (!(new_link = ast_calloc(1, sizeof(*new_link)))) {
+ if (monitor_created) {
+ ao2_ref(new_monitor, -1);
+ }
+ return NULL;
+ }
+
+ AST_LIST_HEAD_INIT(new_monitor->parent_links);
+ AST_LIST_HEAD_INIT(new_monitor->child_links);
+ new_link->child = ao2_ref(new_monitor);
+ new_link->parent = ao2_ref(parent);
+ AST_LIST_INSERT_TAIL(parent->child_links, new_link, next);
+ AST_LIST_INSERT_TAIL(new_monitor->parent_links, new_link, next);
+ return new_monitor;
}
static void interface_tree_to_monitor(struct core_pending_cc_offer *pending_offer, struct cc_core_instance *core_instance)
@@ -839,25 +902,15 @@
struct ast_cc_interface *child_interface_iterator;
ast_assert(strcmp(parent_interface_iterator->monitor_type, "extension") == 0);
- /* Set target here. It will either be a monitor already in the graph or will
- * be created if one does not exist. I'm saving this for a bit though since I think
- * doing a BFS or DFS of the graph for every interface in the pending offer is a
- * bad idea.
- *
- * We can assume here that if we needed to create a new monitor, then it will already
- * have a monitor link set up between it and parent (which will always be the root_monitor
- * here).
- */
+ target = find_or_create_monitor(parent, parent_interface_iterator);
+ /* XXX Do something here in case target is NULL */
parent = target;
AST_LIST_TRAVERSE_SAFE_BEGIN(pending_offer->called_tree, child_interface_iterator, next) {
+ struct ast_cc_monitor *child;
if (child_interface_iterator->parent_id != parent_interface_iterator->id) {
continue;
}
- /* We've found a child of the extension interface we are examining.
- * We need to see if a monitor exists for THIS interface. So we call
- * the same finding/creating function that we did before, only this
- * time, "parent" will be the parent of the newly created/found monitor.
- */
+ child = find_or_create_monitor(parent, child_interface_iterator);
if (strcmp(child_interface_iterator->monitor_type, "extension")) {
/* If we aren't dealing with an extension interface, then we
* can remove it from the list since we know it will have no
@@ -866,8 +919,10 @@
*/
AST_LIST_REMOVE_CURRENT(next);
}
+ ao2_ref(child, -1);
}
AST_LIST_TRAVERSE_SAFE_END;
+ ao2_ref(parent, -1);
}
ao2_unlink(pending_cc_offers, pending_offer);
@@ -1170,6 +1225,11 @@
return -1;
}
ast_log(LOG_NOTICE, "Successfully created core instancess container\n");
+ if (!(cc_monitors = ao2_container_alloc(CC_CORE_INSTANCES_BUCKETS,
+ cc_monitor_hash_fn, cc_monitor_cmp_fn))) {
+ return -1;
+ }
+ ast_log(LOG_NOTICE, "Successfully created monitors container\n");
if (!(cc_core_taskprocessor = ast_taskprocessor_get("CCSS core", TPS_REF_DEFAULT))) {
return -1;
}
More information about the svn-commits
mailing list