[asterisk-commits] mmichelson: branch group/CCSS r215644 - in /team/group/CCSS: include/asterisk...

SVN commits to the Asterisk project asterisk-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 asterisk-commits mailing list