[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