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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 22 13:24:30 CDT 2009


Author: mmichelson
Date: Tue Sep 22 13:24:26 2009
New Revision: 219812

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=219812
Log:
Preliminary available_timer support.

Still to be added are:

1. Address XXX comment about running prune_links, etc. in incorrect thread.
2. Add logic to cancel the available timer when the CC_RECALLING state is reached.
I believe this will require adding a new monitor callback for stopping the running
available timer.


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

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=219812&r1=219811&r2=219812
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Tue Sep 22 13:24:26 2009
@@ -499,6 +499,20 @@
 	/* Which service is being requested? */
 	enum ast_cc_service_type service;
 	/*!
+	 * An ID for the available timer for a corresponding child device
+	 * monitor.
+	 *
+	 * Really, it would seem a bit more logical to have this
+	 * ID reside on the monitor itself, but as far as ease-of-coding
+	 * is concerned, links already exist as something unique per
+	 * instance of a monitor. This way, multiple calls to a single
+	 * monitor may have independent available timers running.
+	 *
+	 * For links between two extension monitors, this field
+	 * never will be used.
+	 */
+	int child_avail_id;
+	/*!
 	 * Why are there two AST_LIST_ENTRY fields in this
 	 * struct? The reason is that each link is in a list
 	 * parent links of one monitor, and in a list of child
@@ -542,7 +556,7 @@
 	/* Allocate callback */
 	int (*init)(struct ast_cc_monitor *monitor, const int core_id);
 	/* Request CCSS callback */
-	int (*request_cc)(struct ast_cc_monitor *monitor, const int core_id, enum ast_cc_service_type service);
+	int (*request_cc)(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
 	/* Suspend monitoring callback */
 	int (*suspend)(struct ast_cc_monitor *monitor, const int core_id);
 	/* Status request callback */

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=219812&r1=219811&r2=219812
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Tue Sep 22 13:24:26 2009
@@ -1197,7 +1197,7 @@
 		core_instance->current_state = args->state;
 		cc_monitor_tree_init(args->core_id);
 		/* It doesn't matter what service we state for the root monitor, so we just use AST_CC_NONE */
-		core_instance->monitor->callbacks->request_cc(core_instance->monitor, args->core_id, AST_CC_NONE);
+		core_instance->monitor->callbacks->request_cc(core_instance->monitor, core_instance->core_id, NULL);
 		break;
 	case CC_ACTIVE:
 		/* Either
@@ -1362,7 +1362,7 @@
 }
 
 static int cc_extension_monitor_init(struct ast_cc_monitor *monitor, const int core_id);
-static int cc_extension_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, enum ast_cc_service_type service);
+static int cc_extension_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
 static int cc_extension_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id);
 static enum ast_device_state cc_extension_monitor_status_request(struct ast_cc_monitor *monitor, const int core_id);
 static int cc_extension_monitor_unsuspend(struct ast_cc_monitor *monitor, const int core_id);
@@ -1387,7 +1387,7 @@
 	return 0;
 }
 
-static int cc_extension_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, enum ast_cc_service_type service)
+static int cc_extension_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link)
 {
 	struct ast_cc_monitor_link *link_iter;
 	AST_LIST_TRAVERSE(&monitor->child_links, link_iter, next_child) {
@@ -1396,7 +1396,7 @@
 		}
 		ast_assert(link_iter->child != NULL);
 		ast_assert(link_iter->child->callbacks != NULL);
-		link_iter->child->callbacks->request_cc(link_iter->child, core_id, link_iter->service);
+		link_iter->child->callbacks->request_cc(link_iter->child, core_id, link_iter);
 		/* XXX Should check the return value and potentially prune
 		 * out monitors that return unsuccessfully since they were
 		 * not able to properly request CC
@@ -1464,7 +1464,7 @@
 }
 
 static int cc_generic_monitor_init(struct ast_cc_monitor *monitor, const int core_id);
-static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, enum ast_cc_service_type service);
+static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
 static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id);
 static enum ast_device_state cc_generic_monitor_status_request(struct ast_cc_monitor *monitor, const int core_id);
 static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor, const int core_id);
@@ -1516,9 +1516,38 @@
 	return;
 }
 
-static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, enum ast_cc_service_type service)
+static int available_timer_expire(const void *data)
+{
+	struct ast_cc_monitor_link *link = (struct ast_cc_monitor_link *) data;
+	struct ast_cc_monitor *parent_monitor = link->parent;
+	struct ast_cc_monitor *child_monitor = link->child;
+	int core_id = link->core_id;
+	/* When an available_timer expires, We just need to
+	 * prune the monitor from the tree. Just because one
+	 * available timer expires doesn't mean we should give
+	 * up monitoring other devices.
+	 */
+	/* XXX WHOA THIS RUNS IN THE WRONG THREAD */
+	prune_links(child_monitor, core_id, link);
+	AST_LIST_REMOVE(&parent_monitor->child_links, link, next_child);
+	destroy_link(link);
+
+	/* Of course, if this link is the only remaining child
+	 * of a parent extension monitor, this means that all the
+	 * other device monitors' available timers have also expired,
+	 * which means we need to request a change to CC_FAILED.
+	 */
+	if (AST_LIST_EMPTY(&parent_monitor->child_links)) {
+		ast_cc_request_state_change(CC_FAILED, core_id, "All available timers have expired");
+	}
+	return 0;
+}
+
+static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link)
 {
 	struct generic_monitor_pvt *gen_mon_pvt = monitor->private_data;
+	enum ast_cc_service_type service = parent_link->service;
+	int when;
 
 	if (gen_mon_pvt->sub) {
 		return 0;
@@ -1545,6 +1574,12 @@
 		return ast_cc_monitor_announce_availability(monitor);
 	}
 
+	when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
+		ast_get_ccnr_available_timer(monitor->interface->config_params);
+
+	parent_link->child_avail_id = ast_sched_thread_add(cc_sched_thread, when * 1000,
+			available_timer_expire, parent_link);
+
 	if (!(gen_mon_pvt->sub = ast_event_subscribe(
 			AST_EVENT_DEVICE_STATE, generic_monitor_devstate_cb, "Requesting CC", monitor, 
 			AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, monitor->interface->name,




More information about the asterisk-commits mailing list