[asterisk-commits] mmichelson: branch group/CCSS r227830 - /team/group/CCSS/main/ccss.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Nov 4 15:04:41 CST 2009
Author: mmichelson
Date: Wed Nov 4 15:04:38 2009
New Revision: 227830
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=227830
Log:
A couple of changes for ast_cc_monitor_failed taskprocessor callback.
The logic was just garbage before. it should work as it is supposed to now.
In addition, the cc_monitor_failed internal function will check if the current
state is CC_RECALLING. If it is, then the monitor failure will be ignored since
the call will result in the proper destructors being called.
Modified:
team/group/CCSS/main/ccss.c
Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=227830&r1=227829&r2=227830
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Wed Nov 4 15:04:38 2009
@@ -2909,61 +2909,66 @@
int core_id;
};
-static int pass_failure_up(struct ast_cc_monitor *monitor, struct ast_cc_monitor_link *parent_link, const int core_id)
-{
- struct ast_cc_monitor *parent_monitor = cc_ref(parent_link->parent, "Ref parent monitor");
- struct ast_cc_monitor_link *link_iter;
-
- /* First things first, kill the link */
- destroy_link(parent_link);
-
- /* Next determine if the parent monitor also needs to pass info up. If the parent monitor
- * has no more links left with this core ID, then it means that it should also pass the
- * failure up.
- */
- AST_LIST_TRAVERSE(&parent_monitor->child_links, link_iter, next_child) {
- if (link_iter->core_id == core_id) {
- break;
- }
- }
-
- cc_unref(monitor, "Killed the link to the failed monitor. Unref it");
-
- if (link_iter) {
- /* There are still child links with this core ID, so this
- * monitor should not pass a failure up the tree
- */
- cc_unref(parent_monitor, "Still child links available. Unref our local reference");
- return 0;
- }
-
- if (parent_monitor->interface->monitor_class == AST_CC_ROOT_MONITOR) {
+static int pass_failure_up(struct ast_cc_monitor *monitor, const int core_id)
+{
+ struct ast_cc_monitor *parent_monitor = NULL;
+ struct ast_cc_monitor_link *child_link_iter;
+ struct ast_cc_monitor_link *parent_link_iter;
+
+ if (monitor->interface->monitor_class == AST_CC_ROOT_MONITOR) {
/* We've reached the top of the tree, which means that what may have
* started as a localized failure has progressed to a global one instead.
*/
- cc_unref(parent_monitor, "Parent is the root. Unref our local reference");
+ ast_log_dynamic_level(cc_logger_level, "All monitors for core %d have failed\n", core_id);
+ cc_unref(monitor, "monitor is the root. failure has reached the top");
return ast_cc_failed(core_id, "All monitors have failed");
}
- /* The parent monitor is an extension monitor who no longer has any children with
- * this core_id. We need to pass the failure up to the next parent monitor in the tree.
- */
- AST_LIST_TRAVERSE(&parent_monitor->parent_links, link_iter, next_parent) {
- if (link_iter->core_id == core_id) {
+ /* Since this is not the root monitor, there SHOULD be a parent link with the
+ * correct core_id. We need to cut it away.
+ */
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&monitor->parent_links, parent_link_iter, next_parent) {
+ if (parent_link_iter->core_id == core_id) {
+ parent_monitor = cc_ref(parent_link_iter->parent, "Found a parent monitor perhaps");
+ AST_LIST_REMOVE_CURRENT(next_parent);
+ parent_link_iter->child->callbacks->cancel_available_timer(parent_link_iter->parent,
+ core_id, &parent_link_iter->child_avail_id);
+ destroy_link(parent_link_iter);
break;
}
}
-
- if (!link_iter) {
- /* The parent monitor doesn't have a parent link with our core_id? WHAT?! */
- cc_unref(parent_monitor, "Parent didn't have an upstream link with proper core ID. Unref");
- return -1;
- }
-
- /* This invocation of pass_failure_up will result in the parent_monitor
- * being unreffed properly, so we don't have to do it here.
- */
- pass_failure_up(parent_monitor, link_iter, core_id);
+ AST_LIST_TRAVERSE_SAFE_END;
+
+ /* If this assertion fails, something is terribly wrong */
+ ast_assert(parent_monitor != NULL);
+
+ if (AST_LIST_EMPTY(&monitor->child_links) && AST_LIST_EMPTY(&monitor->parent_links)) {
+ /* No more links have references to this monitor, so unlink it */
+ ao2_t_unlink(cc_monitors, monitor, "Failed monitor is an orphan. Unlink it");
+ }
+
+ cc_unref(monitor, "Monitor failure has been taken care of. Unref");
+
+ /* Next determine if the parent monitor also needs to pass info up. If the parent monitor
+ * has no more child links left with this core ID, then it means that it should also pass the
+ * failure up.
+ */
+ AST_LIST_TRAVERSE(&parent_monitor->child_links, child_link_iter, next_child) {
+ if (child_link_iter->core_id == core_id) {
+ /* There are still child links with this core ID, so this
+ * monitor should not pass a failure up the tree
+ */
+ cc_unref(parent_monitor, "Still child links available. Unref our local reference");
+ return 0;
+ }
+ }
+
+ /* The parent monitor is a monitor who no longer has any children with
+ * this core_id. We need to pass the failure up to the next parent monitor in the tree.
+ * This invocation of pass_failure_up will unref the parent_monitor. We don't need
+ * to do it ourselves.
+ */
+ pass_failure_up(parent_monitor, core_id);
return 0;
}
@@ -2973,22 +2978,30 @@
struct cc_monitor_failure_data *failure_data = data;
int core_id = failure_data->core_id;
struct ast_cc_monitor *monitor = failure_data->monitor;
- struct ast_cc_monitor_link *parent_link;
+ struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
ast_free(failure_data);
- AST_LIST_TRAVERSE(&monitor->parent_links, parent_link, next_parent) {
- if (parent_link->core_id == core_id) {
- break;
- }
- }
-
- if (!parent_link) {
- cc_unref(monitor, "Can't find a parent link to report failure on. Unref monitor.");
- return -1;
- }
-
- return pass_failure_up(monitor, parent_link, core_id);
+ if (!core_instance) {
+ /* Odd */
+ cc_unref(monitor, "Couldn't find a matching core_instance. Unref monitor");
+ return -1;
+ }
+
+ if (core_instance->current_state == CC_RECALLING) {
+ /* If a monitor reports failure while the core is in the recalling state,
+ * then that actually likely means that the downstream entity has sent
+ * us a message to tear things down, but that CC actually completed successfully
+ * at that point. Since we know that the core_instance will be destroyed when
+ * CC completes here, we can simply ignore this and let things get destroyed
+ * naturally
+ */
+ ast_log_dynamic_level(cc_logger_level, "Ignoring monitor failure since we are in the recalling state\n");
+ cc_unref(monitor, "In recall state, no need to propagate failure. Unref");
+ return 0;
+ }
+
+ return pass_failure_up(monitor, core_id);
}
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const monitor_type)
More information about the asterisk-commits
mailing list