[asterisk-commits] mmichelson: branch group/CCSS_Monitor_Restructure r242088 - /team/group/CCSS_...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jan 21 16:14:30 CST 2010


Author: mmichelson
Date: Thu Jan 21 16:14:27 2010
New Revision: 242088

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=242088
Log:
Write new version of ast_cc_monitor_failed


Modified:
    team/group/CCSS_Monitor_Restructure/main/ccss.c

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=242088&r1=242087&r2=242088
==============================================================================
--- team/group/CCSS_Monitor_Restructure/main/ccss.c (original)
+++ team/group/CCSS_Monitor_Restructure/main/ccss.c Thu Jan 21 16:14:27 2010
@@ -1271,7 +1271,9 @@
 {
 	/* During the monitor creation process, it is possible for this
 	 * function to be called prior to when callbacks are assigned
-	 * to the monitor
+	 * to the monitor. Also, extension monitors do not have callbacks
+	 * assigned to them, so we wouldn't want to segfault when we try
+	 * to destroy one of them.
 	 */
 	if (monitor->callbacks) {
 		monitor->callbacks->cancel_available_timer2(monitor->private_data, &monitor->available_timer_id);
@@ -2316,18 +2318,6 @@
 	ao2_callback(cc_monitors, OBJ_NODATA, print_debug, NULL);
 #endif
 	return monitor;
-}
-
-static struct ast_cc_monitor *find_monitor(const char * const name, const char * const type)
-{
-	struct ast_cc_interface *finder_interface = alloca(sizeof(*finder_interface) + strlen(name));
-	struct ast_cc_monitor finder;
-
-	strcpy(finder_interface->name, name);
-	finder_interface->monitor_type = type;
-	finder.interface = finder_interface;
-
-	return ao2_t_find(cc_monitors, &finder, OBJ_POINTER, "Trying to find specific monitor");
 }
 
 struct cc_state_change_args {
@@ -2987,7 +2977,8 @@
 }
 
 struct cc_monitor_failure_data {
-	struct ast_cc_monitor *monitor;
+	const char *device_name;
+	const char *monitor_type;
 	int core_id;
 };
 
@@ -3060,58 +3051,55 @@
 static int cc_monitor_failed(void *data)
 {
 	struct cc_monitor_failure_data *failure_data = data;
-	int core_id = failure_data->core_id;
-	struct ast_cc_monitor *monitor = failure_data->monitor;
-	struct cc_core_instance *core_instance = find_cc_core_instance(core_id);
-
-	ast_free(failure_data);
-
-	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");
-		cc_unref(core_instance, "In recall state, unref local ref of core_instance");
-		return 0;
-	}
-
-	cc_unref(core_instance, "Done with ref of core instance in cc_monitor_failed");
-	return pass_failure_up(monitor, core_id);
+	struct cc_core_instance *core_instance = find_cc_core_instance(failure_data->core_id);
+	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 (!strcmp(monitor_iter->interface->name, failure_data->device_name) &&
+					!strcmp(monitor_iter->interface->monitor_type, failure_data->monitor_type)) {
+				AST_DLLIST_REMOVE_CURRENT(next);
+				cc_monitor_destroy(monitor_iter);
+			}
+		} else if (!has_children(monitor_iter)) {
+			AST_DLLIST_REMOVE_CURRENT(next);
+			cc_monitor_destroy(monitor_iter);
+		}
+	}
+	AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
+
+	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
+		ast_cc_failed(core_instance->core_id, "All monitors have failed\n");
+	}
+	return 0;
 }
 
 int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const monitor_type)
 {
-	struct ast_cc_monitor *monitor = find_monitor(monitor_name, monitor_type);
 	struct cc_monitor_failure_data *failure_data;
 	int res;
 
-	if (!monitor) {
-		ast_log(LOG_WARNING, "Couldn't find a monitor with name %s and type %s\n", monitor_name, monitor_type);
-		return -1;
-	}
-
 	if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
-		cc_unref(monitor, "Failed to allocate failure data, unref monitor that we found");
-		return -1;
-	}
-
-	failure_data->monitor = monitor; /* No need to ref since find_monitor already did that */
+		return -1;
+	}
+
+	if (!(failure_data->device_name = ast_strdup(monitor_name))) {
+		ast_free(failure_data);
+		return -1;
+	}
+
+	if (!(failure_data->monitor_type = ast_strdup(monitor_type))) {
+		ast_free((char *)failure_data->device_name);
+		ast_free(failure_data);
+		return -1;
+	}
+
 	failure_data->core_id = core_id;
 
 	res = ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data);
 	if (res) {
-		cc_unref(monitor, "ast_taskprocessor_push failed, unref monitor that we found");
+		ast_free((char *)failure_data->device_name);
+		ast_free((char *)failure_data->monitor_type);
 		ast_free(failure_data);
 	}
 	return res;




More information about the asterisk-commits mailing list