[asterisk-commits] rmudgett: branch rmudgett/parking r331096 - in /team/rmudgett/parking: config...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Aug 8 17:51:15 CDT 2011


Author: rmudgett
Date: Mon Aug  8 17:51:11 2011
New Revision: 331096

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=331096
Log:
* Must activate parking lots after removing dead dialplan items to
guarantee that the active parking lots have their dialplan items.

* Added parking lot dialplan items without using a context pointer.  The
context pointer could under very unlikely reload conditions become stale.

* Fix a potential reentrancy condition in ast_context_find_or_create()
when creating the contexts_table.

Modified:
    team/rmudgett/parking/configs/features.conf.sample
    team/rmudgett/parking/main/features.c
    team/rmudgett/parking/main/pbx.c

Modified: team/rmudgett/parking/configs/features.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/parking/configs/features.conf.sample?view=diff&rev=331096&r1=331095&r2=331096
==============================================================================
--- team/rmudgett/parking/configs/features.conf.sample (original)
+++ team/rmudgett/parking/configs/features.conf.sample Mon Aug  8 17:51:11 2011
@@ -66,6 +66,9 @@
                                 ; Operates on all parking lots.
 ;adsipark = yes                 ; if you want ADSI parking announcements
                                 ; Operates on all parking lots.
+;findslot => next               ; Continue to the 'next' free parking space.
+                                ; Defaults to 'first' available
+                                ; Set per parking lot.
 ;parkedmusicclass=default       ; This is the MOH class to use for the parked channel
                                 ; as long as the class is not set on the channel directly
                                 ; using Set(CHANNEL(musicclass)=whatever) in the dialplan

Modified: team/rmudgett/parking/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/parking/main/features.c?view=diff&rev=331096&r1=331095&r2=331096
==============================================================================
--- team/rmudgett/parking/main/features.c (original)
+++ team/rmudgett/parking/main/features.c Mon Aug  8 17:51:11 2011
@@ -455,9 +455,7 @@
  * The list belongs to a parkinglot.
  */
 struct parkeduser {
-/* BUGBUG need to make hold a channel reference! */
-	/*! Parked channel. */
-	struct ast_channel *chan;
+	struct ast_channel *chan;                   /*!< Parked channel */
 	struct timeval start;                       /*!< Time the park started */
 	int parkingnum;                             /*!< Parking lot space used */
 	char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
@@ -478,6 +476,7 @@
 
 /*! Parking lot configuration options. */
 struct parkinglot_cfg {
+/* BUGBUG need to reimplement parking findslot option.  Broken since -r114655 */
 	/*! Music class used for parking */
 	char mohclass[MAX_MUSICCLASS];
 	/*! Extension to park calls in this parking lot. */
@@ -1314,9 +1313,9 @@
 /* Park a call */
 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
 {
-	struct ast_context *con;
 	struct parkeduser *pu = args->pu;
 	const char *event_from;
+	char app_data[AST_MAX_EXTENSION + AST_MAX_CONTEXT];
 
 	if (pu == NULL) {
 		args->pu = pu = park_space_reserve(chan, peer, args);
@@ -1450,18 +1449,14 @@
 		ast_adsi_unload_session(peer);
 	}
 
-	con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->cfg.parking_con, registrar);
-	if (!con) { /* Still no context? Bad */
-		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", pu->parkinglot->cfg.parking_con);
+	snprintf(app_data, sizeof(app_data), "%s,%s", pu->parkingexten,
+		pu->parkinglot->name);
+	if (ast_add_extension(pu->parkinglot->cfg.parking_con, 1, pu->parkingexten, 1,
+		NULL, NULL, parkedcall, ast_strdup(app_data), ast_free_ptr, registrar)) {
+		ast_log(LOG_ERROR, "Could not create parked call exten: %s@%s\n",
+			pu->parkingexten, pu->parkinglot->cfg.parking_con);
 	} else {
-		char app_data[AST_MAX_EXTENSION + AST_MAX_CONTEXT];
-
-		snprintf(app_data, sizeof(app_data), "%s,%s", pu->parkingexten,
-			pu->parkinglot->name);
-		if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall,
-			ast_strdup(app_data), ast_free_ptr, registrar)) {
-			notify_metermaids(pu->parkingexten, pu->parkinglot->cfg.parking_con, AST_DEVICE_INUSE);
-		}
+		notify_metermaids(pu->parkingexten, pu->parkinglot->cfg.parking_con, AST_DEVICE_INUSE);
 	}
 
 	AST_LIST_UNLOCK(&pu->parkinglot->parkings);
@@ -4319,7 +4314,6 @@
 	struct ast_channel *chan = pu->chan;	/* shorthand */
 	int tms;        /* timeout for this item */
 	int x;          /* fd index in channel */
-	struct ast_context *con;
 	int parking_complete = 0;
 
 	tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
@@ -4360,8 +4354,7 @@
 				}
 			}
 
-			con = ast_context_find_or_create(NULL, NULL, parking_con_dial, registrar);
-			if (!con) {
+			if (!ast_context_find_or_create(NULL, NULL, parking_con_dial, registrar)) {
 				ast_log(LOG_ERROR,
 					"Parking dial context '%s' does not exist and unable to create\n",
 					parking_con_dial);
@@ -4390,8 +4383,12 @@
 				}
 				ast_channel_unlock(chan);
 
-				ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial",
-					ast_strdup(returnexten), ast_free_ptr, registrar);
+				if (ast_add_extension(parking_con_dial, 1, peername_flat, 1, NULL, NULL,
+					"Dial", ast_strdup(returnexten), ast_free_ptr, registrar)) {
+					ast_log(LOG_ERROR,
+						"Could not create parking return dial exten: %s@%s\n",
+						peername_flat, parking_con_dial);
+				}
 			}
 			if (pu->options_specified) {
 				/*
@@ -5214,7 +5211,6 @@
 static int parkinglot_activate(struct ast_parkinglot *parkinglot)
 {
 	int disabled = 0;
-	struct ast_context *con;
 	char app_data[5 + AST_MAX_CONTEXT];
 
 	/* Create Park option list.  Must match with struct park_app_args options. */
@@ -5227,15 +5223,14 @@
 	}
 
 	/* Create context */
-	con = ast_context_find_or_create(NULL, NULL, parkinglot->cfg.parking_con, registrar);
-	if (!con) {
+	if (!ast_context_find_or_create(NULL, NULL, parkinglot->cfg.parking_con, registrar)) {
 		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n",
 			parkinglot->cfg.parking_con);
 		disabled = 1;
 
 	/* Add a parking extension into the context */
-	} else if (ast_add_extension2(con, 1, parkinglot->cfg.parkext, 1, NULL, NULL,
-		parkcall, ast_strdup(app_data), ast_free_ptr, registrar)) {
+	} else if (ast_add_extension(parkinglot->cfg.parking_con, 1, parkinglot->cfg.parkext,
+		1, NULL, NULL, parkcall, ast_strdup(app_data), ast_free_ptr, registrar)) {
 		ast_log(LOG_ERROR, "Could not create parking lot %s access exten %s@%s\n",
 			parkinglot->name, parkinglot->cfg.parkext, parkinglot->cfg.parking_con);
 		disabled = 1;
@@ -5295,7 +5290,8 @@
 	if (oldparkinglot) {
 		if (cfg_error) {
 			/* Bad configuration read.  Keep using the original config. */
-			ast_debug(1, "Changes to parking lot %s are discarded.\n", parkinglot->name);
+			ast_log(LOG_WARNING, "Changes to parking lot %s are discarded.\n",
+				parkinglot->name);
 			cfg_error = 0;
 		} else if (!AST_LIST_EMPTY(&parkinglot->parkings)
 			&& memcmp(&new_cfg, &parkinglot->cfg, sizeof(parkinglot->cfg))) {
@@ -5314,23 +5310,14 @@
 	}
 	parkinglot->the_mark = 0;
 
-	if (cfg_error || parkinglot_activate(parkinglot)) {
-		ast_log(LOG_WARNING, "Parking lot %s not open for business.\n", parkinglot->name);
-		if (oldparkinglot) {
-			/*
-			 * The old parking lot failed to activate most likely because of
-			 * changes.  Allow reloading later to see if that fixes it.
-			 */
-			force_reload_load = 1;
-		}
-		ao2_unlock(parkinglot);
+	ao2_unlock(parkinglot);
+
+	if (cfg_error) {
+		/* Only new parking lots could have config errors here. */
+		ast_log(LOG_WARNING, "New parking lot %s is discarded.\n", parkinglot->name);
 		parkinglot_unref(parkinglot);
 		return NULL;
 	}
-	ao2_unlock(parkinglot);
-
-	ast_debug(1, "Parking lot %s now open for business. (parkpos %d-%d)\n",
-		parkinglot->name, parkinglot->cfg.parking_start, parkinglot->cfg.parking_stop);
 
 	/* Move it into the list, if it wasn't already there */
 	if (!oldparkinglot) {
@@ -6010,8 +5997,10 @@
 {
 	struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
 
+ast_log(LOG_NOTICE, "BUGBUG Request to remove exten: %s@%s priority:%d\n", exten, context, priority);
 	if (pbx_find_extension(NULL, NULL, &q, context, exten, priority, NULL, NULL,
 		E_MATCH)) {
+ast_log(LOG_NOTICE, "BUGBUG Removing exten: %s@%s priority:%d\n", exten, context, priority);
 		ast_context_remove_extension(context, exten, priority, registrar);
 	}
 }
@@ -6265,9 +6254,29 @@
 	return 0;
 }
 
+static int parkinglot_activate_cb(void *obj, void *arg, int flags)
+{
+	struct ast_parkinglot *parkinglot = obj;
+
+	if (parkinglot_activate(parkinglot)) {
+		/*
+		 * The parking lot failed to activate.  Allow reloading later to
+		 * see if that fixes it.
+		 */
+		force_reload_load = 1;
+		ast_log(LOG_WARNING, "Parking lot %s not open for business.\n", parkinglot->name);
+	} else {
+		ast_debug(1, "Parking lot %s now open for business. (parkpos %d-%d)\n",
+			parkinglot->name, parkinglot->cfg.parking_start,
+			parkinglot->cfg.parking_stop);
+	}
+
+	return 0;
+}
+
 static int load_config(int reload)
 {
-#ifdef BUGBUG
+#ifdef BUGBUG	// Force to always reload features
 	struct ast_flags config_flags = {
 		reload && !force_reload_load ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 #else
@@ -6336,6 +6345,9 @@
 
 	destroy_dialplan_usage_map(&old_usage_map);
 	destroy_dialplan_usage_map(&new_usage_map);
+
+	ao2_t_callback(parkinglots, OBJ_NODATA, parkinglot_activate_cb, NULL,
+		"callback to activate all parking lots");
 
 	return 0;
 }

Modified: team/rmudgett/parking/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/parking/main/pbx.c?view=diff&rev=331096&r1=331095&r2=331096
==============================================================================
--- team/rmudgett/parking/main/pbx.c (original)
+++ team/rmudgett/parking/main/pbx.c Mon Aug  8 17:51:11 2011
@@ -7010,12 +7010,17 @@
 	int length = sizeof(struct ast_context) + strlen(name) + 1;
 
 	if (!contexts_table) {
-		contexts_table = ast_hashtab_create(17,
-										   ast_hashtab_compare_contexts,
-										   ast_hashtab_resize_java,
-										   ast_hashtab_newsize_java,
-										   ast_hashtab_hash_contexts,
-										   0);
+		/* Protect creation of contexts_table from reentrancy. */
+		ast_wrlock_contexts();
+		if (!contexts_table) {
+			contexts_table = ast_hashtab_create(17,
+				ast_hashtab_compare_contexts,
+				ast_hashtab_resize_java,
+				ast_hashtab_newsize_java,
+				ast_hashtab_hash_contexts,
+				0);
+		}
+		ast_unlock_contexts();
 	}
 
 	ast_copy_string(search.name, name, sizeof(search.name));
@@ -7235,7 +7240,7 @@
 
 	begintime = ast_tvnow();
 	ast_mutex_lock(&context_merge_lock);/* Serialize ast_merge_contexts_and_delete */
-	ast_rdlock_contexts();
+	ast_wrlock_contexts();
 	iter = ast_hashtab_start_traversal(contexts_table);
 	while ((tmp = ast_hashtab_next(iter))) {
 		context_merge(extcontexts, exttable, tmp, registrar);




More information about the asterisk-commits mailing list