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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 22 16:27:14 CST 2010


Author: mmichelson
Date: Fri Jan 22 16:27:09 2010
New Revision: 242476

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=242476
Log:
Place locks around operations on the monitor list.

In most cases, this probably isn't necessary, but I would like
to make sure that the core doesn't try to mess with a list while
a channel driver is traversing it to set up the CC_INTERFACES
channel variable or some such. Most of this is being overly
protective, but it'll be all right.

I also messed a bit with the locking of the channel and reference
counts of the recall data interface list when setting the CC_INTERFACES
channel variable.


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=242476&r1=242475&r2=242476
==============================================================================
--- team/group/CCSS_Monitor_Restructure/main/ccss.c (original)
+++ team/group/CCSS_Monitor_Restructure/main/ccss.c Fri Jan 22 16:27:09 2010
@@ -2292,6 +2292,7 @@
 static void request_cc(struct cc_core_instance *core_instance)
 {
 	struct ast_cc_monitor *monitor_iter;
+	AST_DLLIST_LOCK(core_instance->monitors);
 	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_cc(monitor_iter, &monitor_iter->available_timer_id)) {
@@ -2312,6 +2313,7 @@
 	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
 		ast_cc_failed(core_instance->core_id, "All device monitors failed to request CC");
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 }
 
 static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
@@ -2334,6 +2336,7 @@
 static void unsuspend(struct cc_core_instance *core_instance)
 {
 	struct ast_cc_monitor *monitor_iter;
+	AST_DLLIST_LOCK(core_instance->monitors);
 	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->unsuspend(monitor_iter)) {
@@ -2348,6 +2351,7 @@
 	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
 		ast_cc_failed(core_instance->core_id, "All device monitors failed to unsuspend CC");
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 }
 
 static int cc_active(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
@@ -2381,6 +2385,7 @@
 static void suspend(struct cc_core_instance *core_instance)
 {
 	struct ast_cc_monitor *monitor_iter;
+	AST_DLLIST_LOCK(core_instance->monitors);
 	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->suspend(monitor_iter)) {
@@ -2397,6 +2402,7 @@
 	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
 		ast_cc_failed(core_instance->core_id, "All device monitors failed to suspend CC");
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 }
 
 static int cc_caller_busy(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
@@ -2416,6 +2422,7 @@
 static void cancel_available_timer(struct cc_core_instance *core_instance)
 {
 	struct ast_cc_monitor *monitor_iter;
+	AST_DLLIST_LOCK(core_instance->monitors);
 	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->cancel_available_timer(monitor_iter, &monitor_iter->available_timer_id)) {
@@ -2430,6 +2437,7 @@
 	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
 		ast_cc_failed(core_instance->core_id, "All device monitors failed to cancel their available timers");
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 }
 
 static int cc_recalling(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
@@ -2660,13 +2668,13 @@
 	 * Now we need to find out if the channel device name
 	 * is in the list of interfaces in the called tree.
 	 */
-	AST_LIST_LOCK(interface_tree);
-	AST_LIST_TRAVERSE(interface_tree, device_monitor, next) {
+	AST_DLLIST_LOCK(interface_tree);
+	AST_DLLIST_TRAVERSE(interface_tree, device_monitor, next) {
 		if (!strcmp(device_monitor->interface->name, device_name) &&
 				!strcmp(device_monitor->interface->monitor_type, monitor_type)) {
 			/* 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);
 			cc_unref(interface_tree, "Found a match in recall tree.");
 			return 1;
 		}
@@ -2695,7 +2703,9 @@
 	}
 
 	recall_data = recall_datastore->data;
-	interface_tree = recall_data->interface_tree;
+	interface_tree = cc_ref(recall_data->interface_tree, "Getting ref of recall interface tree");
+	ast_channel_unlock(chan);
+	AST_DLLIST_LOCK(interface_tree);
 	monitor_iter = AST_DLLIST_FIRST(interface_tree);
 	top_level_id = monitor_iter->id;
 
@@ -2707,11 +2717,12 @@
 			ast_copy_string(previous_dialable_name, dialable_name, sizeof(previous_dialable_name));
 		}
 	}
+	AST_DLLIST_UNLOCK(interface_tree);
 
 	pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(var_value));
 	ast_log_dynamic_level(cc_logger_level, "CC_INTERFACES set to %s\n", ast_str_buffer(var_value));
-	ast_channel_unlock(chan);
 	ast_free(var_value);
+	cc_unref(interface_tree, "Done with interface tree while setting CC_INTERFACES");
 	return 0;
 }
 
@@ -2734,8 +2745,10 @@
 	}
 
 	recall_data = recall_datastore->data;
-	interface_tree = recall_data->interface_tree;
-
+	interface_tree = cc_ref(recall_data->interface_tree, "Get reference to recall data interface tree");
+	ast_channel_unlock(chan);
+
+	AST_DLLIST_LOCK(interface_tree);
 	AST_DLLIST_TRAVERSE(interface_tree, monitor_iter, next) {
 		if (!strcmp(monitor_iter->interface->name, extension)) {
 			exten_id = monitor_iter->id;
@@ -2749,7 +2762,8 @@
 		 * the admin has changed a CC_INTERFACES variable at some point.
 		 */
 		ast_free(var_value);
-		ast_channel_unlock(chan);
+		AST_DLLIST_UNLOCK(interface_tree);
+		cc_unref(interface_tree, "Couldn't find the extension specified");
 		return -1;
 	}
 
@@ -2763,11 +2777,11 @@
 			ast_copy_string(previous_dialable_name, dialable_name, sizeof(previous_dialable_name));
 		}
 	}
-
+	AST_DLLIST_UNLOCK(interface_tree);
 	pbx_builtin_setvar_helper(chan, "CC_INTERFACES", ast_str_buffer(var_value));
 	ast_log_dynamic_level(cc_logger_level, "CC_INTERFACES set to %s\n", ast_str_buffer(var_value));
-	ast_channel_unlock(chan);
 	ast_free(var_value);
+	cc_unref(interface_tree, "Done writing the CC_INTERFACES channel variable");
 	return 0;
 }
 
@@ -2895,6 +2909,7 @@
 	struct cc_core_instance *core_instance = find_cc_core_instance(failure_data->core_id);
 	struct ast_cc_monitor *monitor_iter;
 
+	AST_DLLIST_LOCK(core_instance->monitors);
 	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) &&
@@ -2912,6 +2927,7 @@
 	if (AST_DLLIST_EMPTY(core_instance->monitors)) {
 		ast_cc_failed(core_instance->core_id, "All monitors have failed\n");
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 	return 0;
 }
 
@@ -3047,12 +3063,14 @@
 
 	ast_free(args);
 
+	AST_DLLIST_LOCK(core_instance->monitors);
 	AST_DLLIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
 		if (monitor_iter->interface->monitor_class == AST_CC_DEVICE_MONITOR &&
 				monitor_iter->callbacks->status_response) {
 			monitor_iter->callbacks->status_response(monitor_iter, devstate);
 		}
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 	cc_unref(core_instance, "Status response finished. Unref core instance");
 	return 0;
 }
@@ -3294,6 +3312,7 @@
 	const char *monitor_type = cb_data->monitor_type;
 	struct ast_cc_monitor *monitor_iter;
 
+	AST_DLLIST_LOCK(core_instance->monitors);
 	AST_DLLIST_TRAVERSE(core_instance->monitors, monitor_iter, next) {
 		if (!strcmp(monitor_iter->interface->name, device_name) && 
 				!strcmp(monitor_iter->interface->monitor_type, monitor_type)) {
@@ -3301,6 +3320,7 @@
 			break;
 		}
 	}
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 	return 0;
 }
 
@@ -3368,7 +3388,9 @@
 
 	ast_cli(*cli_fd, "%d\t\t%s\t\t%s\n", core_instance->core_id, core_instance->agent->interface,
 			cc_state_to_string(core_instance->current_state));
+	AST_DLLIST_LOCK(core_instance->monitors);
 	cc_cli_print_monitor_stats(AST_DLLIST_FIRST(core_instance->monitors), *cli_fd, 0);
+	AST_DLLIST_UNLOCK(core_instance->monitors);
 	return 0;
 }
 




More information about the asterisk-commits mailing list