[asterisk-commits] mmichelson: branch group/CCSS_Monitor_Restructure r241362 - in /team/group/CC...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 19 16:35:29 CST 2010


Author: mmichelson
Date: Tue Jan 19 16:35:25 2010
New Revision: 241362

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=241362
Log:
Next batch of progress that compiles.

First, I've changed the interface list to be doubly-linked. The
main reason for this is to be able to do the types of traversals
I'll need when calling monitor callbacks. For an example of
how it is used, see the request_cc function in ccss.c

I'll be using the template that I've made in request_cc for
the other instances where I call monitor callbacks next. For
now, the new monitor callbacks are getting a "2" appended to
their names. Once I remove the original monitor callbacks,
the "2" will be removed.


Modified:
    team/group/CCSS_Monitor_Restructure/include/asterisk/ccss.h
    team/group/CCSS_Monitor_Restructure/main/ccss.c

Modified: team/group/CCSS_Monitor_Restructure/include/asterisk/ccss.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS_Monitor_Restructure/include/asterisk/ccss.h?view=diff&rev=241362&r1=241361&r2=241362
==============================================================================
--- team/group/CCSS_Monitor_Restructure/include/asterisk/ccss.h (original)
+++ team/group/CCSS_Monitor_Restructure/include/asterisk/ccss.h Tue Jan 19 16:35:25 2010
@@ -27,6 +27,7 @@
 #include "asterisk.h"
 
 #include "asterisk/linkedlists.h"
+#include "asterisk/dlinkedlists.h"
 #include "asterisk/devicestate.h"
 
 enum ast_cc_service_type {
@@ -487,6 +488,8 @@
 	AST_CC_ROOT_MONITOR,
 };
 
+/* Forward declaration */
+struct cc_monitor;
 /*!
  * \brief Structure that represents a CCSS monitor
  * \details
@@ -558,6 +561,7 @@
 	 * \retval -1 on failure.
 	 */
 	int (*request_cc)(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
+	int (*request_cc2)(struct cc_monitor *monitor, int *available_timer_id);
 	/*!
 	 * \brief Suspend monitoring.
 	 *

Modified: team/group/CCSS_Monitor_Restructure/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS_Monitor_Restructure/main/ccss.c?view=diff&rev=241362&r1=241361&r2=241362
==============================================================================
--- team/group/CCSS_Monitor_Restructure/main/ccss.c (original)
+++ team/group/CCSS_Monitor_Restructure/main/ccss.c Tue Jan 19 16:35:25 2010
@@ -1265,10 +1265,16 @@
 	 */
 	int available_timer_id;
 	/*!
+	 * Boolean to indicate that we have requested CC on this interface.
+	 * This prevents us from attempting to request CC on an interface more
+	 * than once.
+	 */
+	int cc_requested;
+	/*!
 	 * Monitor callbacks
 	 */
 	const struct ast_cc_monitor_callbacks *callbacks;
-	AST_LIST_ENTRY(cc_monitor) next;
+	AST_DLLIST_ENTRY(cc_monitor) next;
 };
 
 /*!
@@ -1278,7 +1284,7 @@
  * to use it, and it may last beyond the lifetime of a single
  * thread.
  */
-AST_LIST_HEAD(ast_cc_interface_tree, cc_monitor);
+AST_DLLIST_HEAD(ast_cc_interface_tree, cc_monitor);
 
 static void cc_interface_destroy(void *data)
 {
@@ -1298,10 +1304,10 @@
 {
 	struct ast_cc_interface_tree *cc_interface_tree = data;
 	struct cc_monitor *monitor;
-	while ((monitor = AST_LIST_REMOVE_HEAD(cc_interface_tree, next))) {
+	while ((monitor = AST_DLLIST_REMOVE_HEAD(cc_interface_tree, next))) {
 		cc_monitor_destroy(monitor);
 	}
-	AST_LIST_HEAD_DESTROY(cc_interface_tree);
+	AST_DLLIST_HEAD_DESTROY(cc_interface_tree);
 }
 
 /*!
@@ -1550,8 +1556,8 @@
 	}
 
 	/* Finally, all that allocation is done... */
-	AST_LIST_HEAD_INIT(interfaces->interface_tree);
-	AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
+	AST_DLLIST_HEAD_INIT(interfaces->interface_tree);
+	AST_DLLIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
 	dial_cc_datastore->data = interfaces;
 	dial_cc_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
 	interfaces->dial_parent_id = monitor->id;
@@ -1726,16 +1732,16 @@
 	 * This traversal helps us to not create duplicate tree items in
 	 * case a device queues multiple CC control frames.
 	 */
-	AST_LIST_LOCK(cc_interfaces->interface_tree);
-	AST_LIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
+	AST_DLLIST_LOCK(cc_interfaces->interface_tree);
+	AST_DLLIST_TRAVERSE(cc_interfaces->interface_tree, monitor, next) {
 		if (!strcmp(monitor->interface->name, device_name)) {
 			ast_log_dynamic_level(cc_logger_level, "Device %s sent us multiple CC control frames. Ignoring those beyond the first.\n", device_name);
-			AST_LIST_UNLOCK(cc_interfaces->interface_tree);
+			AST_DLLIST_UNLOCK(cc_interfaces->interface_tree);
 			cc_unref(core_instance, "Returning early from ast_handle_cc_control_frame");
 			return;
 		}
 	}
-	AST_LIST_UNLOCK(cc_interfaces->interface_tree);
+	AST_DLLIST_UNLOCK(cc_interfaces->interface_tree);
 
 
 	if (!(monitor = cc_device_monitor_init(device_name, dialable_name, cc_data))) {
@@ -1744,9 +1750,9 @@
 		return;
 	}
 
-	AST_LIST_LOCK(cc_interfaces->interface_tree);
-	AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
-	AST_LIST_UNLOCK(cc_interfaces->interface_tree);
+	AST_DLLIST_LOCK(cc_interfaces->interface_tree);
+	AST_DLLIST_INSERT_TAIL(cc_interfaces->interface_tree, monitor, next);
+	AST_DLLIST_UNLOCK(cc_interfaces->interface_tree);
 
 	manager_event(EVENT_FLAG_CC, "CCAvailable",
 		"CoreID: %d\r\n"
@@ -1818,9 +1824,9 @@
 	 * on the datastore, so we need to copy that into this monitor.
 	 */
 	monitor->dialable_name = ast_strdup(interfaces->current_extension_dialable_name);
-	AST_LIST_LOCK(interfaces->interface_tree);
-	AST_LIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
-	AST_LIST_UNLOCK(interfaces->interface_tree);
+	AST_DLLIST_LOCK(interfaces->interface_tree);
+	AST_DLLIST_INSERT_TAIL(interfaces->interface_tree, monitor, next);
+	AST_DLLIST_UNLOCK(interfaces->interface_tree);
 	interfaces->dial_parent_id = monitor->id;
 	return 0;
 }
@@ -2114,7 +2120,7 @@
 	char *target;
 	int reason;
 	struct ast_channel *chan;
-	struct cc_monitor *monitor = AST_LIST_FIRST(agent->interface_tree);
+	struct cc_monitor *monitor = AST_DLLIST_FIRST(agent->interface_tree);
 	char *full_extension = ast_strdupa(monitor->interface->name);
 	char *context;
 	char *exten;
@@ -2226,8 +2232,8 @@
 	/* Locking is necessary here since a channel thread could possibly be mucking
 	 * with this list while we try to traverse it
 	 */
-	AST_LIST_LOCK(interface_tree);
-	AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
+	AST_DLLIST_LOCK(interface_tree);
+	AST_DLLIST_TRAVERSE(interface_tree, monitor_iter, next) {
 		if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
 			monitor_callbacks =
 				find_monitor_callbacks(monitor_iter->interface->monitor_type);
@@ -2240,7 +2246,7 @@
 			monitor_callbacks->instance_destructor(core_id);
 		}
 	}
-	AST_LIST_UNLOCK(interface_tree);
+	AST_DLLIST_UNLOCK(interface_tree);
 }
 
 static void cc_core_instance_destructor(void *data)
@@ -2574,6 +2580,37 @@
 	return 0;
 }
 
+static int has_children(struct cc_monitor *monitor)
+{
+	struct cc_monitor *iter = monitor;
+
+	while ((iter = AST_DLLIST_NEXT(iter, next))) {
+		if (iter->parent_id == monitor->id) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static void request_cc(struct cc_core_instance *core_instance)
+{
+	struct cc_monitor *monitor_iter;
+	AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(core_instance->monitors, monitor_iter, next) {
+		if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR) {
+			if (monitor_iter->callbacks->request_cc2(monitor_iter, &monitor_iter->available_timer_id)) {
+				AST_DLLIST_REMOVE_CURRENT(next);
+			}
+		} else if (!has_children(monitor_iter)) {
+			AST_DLLIST_REMOVE_CURRENT(next);
+		}
+	}
+	AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
+
+	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
+		ast_cc_failed(core_instance->core_id, "All device monitors failed to request CC");
+	}
+}
+
 static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
 {
 	if (!ast_cc_request_is_within_limits()) {
@@ -2583,6 +2620,7 @@
 	}
 	core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
 	/* It doesn't matter what service we state for the root monitor, so we just use AST_CC_NONE */
+	request_cc(core_instance);
 	core_instance->monitor->callbacks->request_cc(core_instance->monitor, core_instance->core_id, NULL);
 	manager_event(EVENT_FLAG_CC, "CCRequested",
 		"CoreID: %d\r\n"
@@ -2849,8 +2887,8 @@
 	 * a match based on device name and a parent extension tree item with the same extension and
 	 * context as the channel.
 	 */
-	AST_LIST_LOCK(interface_tree);
-	AST_LIST_TRAVERSE(interface_tree, exten_monitor, next) {
+	AST_DLLIST_LOCK(interface_tree);
+	AST_DLLIST_TRAVERSE(interface_tree, exten_monitor, next) {
 		/* First we try to find an extension interface with the proper
 		 * exten and context.
 		 */
@@ -2859,18 +2897,18 @@
 			 * of its children
 			 */
 			struct cc_monitor *device_monitor = exten_monitor;
-			while ((device_monitor = AST_LIST_NEXT(device_monitor, next))) {
+			while ((device_monitor = AST_DLLIST_NEXT(device_monitor, next))) {
 				if ((device_monitor->parent_id == exten_monitor->id) &&
 						!strcmp(device_monitor->interface->name, device_name)) {
 					/* BOOM! Device is in the tree! We have a winner! */
 					*core_id = recall_data->core_id;
-					AST_LIST_UNLOCK(interface_tree);
+					AST_DLLIST_UNLOCK(interface_tree);
 					return 1;
 				}
 			}
 		}
 	}
-	AST_LIST_UNLOCK(interface_tree);
+	AST_DLLIST_UNLOCK(interface_tree);
 	return 0;
 }
 
@@ -2895,7 +2933,7 @@
 	recall_data = recall_datastore->data;
 	interface_tree = recall_data->interface_tree;
 
-	AST_LIST_TRAVERSE(interface_tree, monitor_iter, next) {
+	AST_DLLIST_TRAVERSE(interface_tree, monitor_iter, next) {
 		if (!strcmp(monitor_iter->interface->name, extension)) {
 			exten_id = monitor_iter->id;
 			break;
@@ -2914,7 +2952,7 @@
 
 	/* I kind of feel wrong re-using monitor_iter here, but eh, it works
 	 */
-	while ((monitor_iter = AST_LIST_NEXT(monitor_iter, next))) {
+	while ((monitor_iter = AST_DLLIST_NEXT(monitor_iter, next))) {
 		if (monitor_iter->parent_id == exten_id && strcmp(monitor_iter->dialable_name, previous_dialable_name)) {
 			char *dialable_name = monitor_iter->dialable_name;
 			ast_str_append(&var_value, 0, "%s%s", multi ? "&" : "", dialable_name);




More information about the asterisk-commits mailing list