[svn-commits] mvanbaak: branch group/multiparking r107013 - in /team/group/multiparking: ./...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Sun Mar 9 08:48:27 CDT 2008
Author: mvanbaak
Date: Sun Mar 9 08:48:27 2008
New Revision: 107013
URL: http://svn.digium.com/view/asterisk?view=rev&rev=107013
Log:
merge, resolve conflicts, compile, reset automerge, go!
Modified:
team/group/multiparking/ (props changed)
team/group/multiparking/apps/app_dial.c
team/group/multiparking/apps/app_meetme.c
team/group/multiparking/apps/app_queue.c
team/group/multiparking/channels/chan_iax2.c
team/group/multiparking/channels/chan_sip.c
team/group/multiparking/channels/chan_skinny.c
team/group/multiparking/channels/chan_zap.c
team/group/multiparking/include/asterisk/pbx.h
team/group/multiparking/include/asterisk/pval.h
team/group/multiparking/main/channel.c
team/group/multiparking/main/editline/Makefile.in
team/group/multiparking/main/features.c
team/group/multiparking/main/pbx.c
team/group/multiparking/pbx/pbx_ael.c
team/group/multiparking/pbx/pbx_config.c
team/group/multiparking/res/ael/ael.flex
team/group/multiparking/res/ael/ael.tab.c
team/group/multiparking/res/ael/ael.tab.h
team/group/multiparking/res/ael/ael.y
team/group/multiparking/res/ael/ael_lex.c
team/group/multiparking/res/ael/pval.c
team/group/multiparking/utils/Makefile
team/group/multiparking/utils/ael_main.c
team/group/multiparking/utils/conf2ael.c
team/group/multiparking/utils/extconf.c
Propchange: team/group/multiparking/
------------------------------------------------------------------------------
automerge = yes
Propchange: team/group/multiparking/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/group/multiparking/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Mar 9 08:48:27 2008
@@ -1,1 +1,1 @@
-/trunk:1-106717
+/trunk:1-107012
Modified: team/group/multiparking/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/apps/app_dial.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/apps/app_dial.c (original)
+++ team/group/multiparking/apps/app_dial.c Sun Mar 9 08:48:27 2008
@@ -2096,9 +2096,7 @@
int res;
struct ast_context *con;
- con = ast_context_find("app_dial_gosub_virtual_context");
- if (!con)
- con = ast_context_create(NULL, "app_dial_gosub_virtual_context", "app_dial");
+ con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
if (!con)
ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
else
Modified: team/group/multiparking/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/apps/app_meetme.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/apps/app_meetme.c (original)
+++ team/group/multiparking/apps/app_meetme.c Sun Mar 9 08:48:27 2008
@@ -5280,7 +5280,7 @@
if (!ast_strlen_zero(trunk->autocontext)) {
struct ast_context *context;
- context = ast_context_find_or_create(NULL, trunk->autocontext, sla_registrar);
+ context = ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar);
if (!context) {
ast_log(LOG_ERROR, "Failed to automatically find or create "
"context '%s' for SLA!\n", trunk->autocontext);
@@ -5417,7 +5417,7 @@
if (!ast_strlen_zero(station->autocontext)) {
struct ast_context *context;
struct sla_trunk_ref *trunk_ref;
- context = ast_context_find_or_create(NULL, station->autocontext, sla_registrar);
+ context = ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar);
if (!context) {
ast_log(LOG_ERROR, "Failed to automatically find or create "
"context '%s' for SLA!\n", station->autocontext);
@@ -5510,7 +5510,7 @@
ast_config_destroy(cfg);
- if (!reload)
+ if (!reload && (!AST_LIST_EMPTY(&sla_stations) || !AST_LIST_EMPTY(&sla_stations)))
ast_pthread_create(&sla.thread, NULL, sla_thread, NULL);
return res;
Modified: team/group/multiparking/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/apps/app_queue.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/apps/app_queue.c (original)
+++ team/group/multiparking/apps/app_queue.c Sun Mar 9 08:48:27 2008
@@ -6147,9 +6147,7 @@
if (!reload_queues(0))
return AST_MODULE_LOAD_DECLINE;
- con = ast_context_find("app_queue_gosub_virtual_context");
- if (!con)
- con = ast_context_create(NULL, "app_queue_gosub_virtual_context", "app_queue");
+ con = ast_context_find_or_create(NULL, NULL, "app_queue_gosub_virtual_context", "app_queue");
if (!con)
ast_log(LOG_ERROR, "Queue virtual context 'app_queue_gosub_virtual_context' does not exist and unable to create\n");
else
Modified: team/group/multiparking/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/channels/chan_iax2.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/channels/chan_iax2.c (original)
+++ team/group/multiparking/channels/chan_iax2.c Sun Mar 9 08:48:27 2008
@@ -10788,8 +10788,7 @@
} else if (!strcasecmp(v->name, "regcontext")) {
ast_copy_string(regcontext, v->value, sizeof(regcontext));
/* Create context if it doesn't exist already */
- if (!ast_context_find(regcontext))
- ast_context_create(NULL, regcontext, "IAX2");
+ ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
} else if (!strcasecmp(v->name, "tos")) {
if (ast_str2tos(v->value, &tos))
ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
Modified: team/group/multiparking/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/channels/chan_sip.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/channels/chan_sip.c (original)
+++ team/group/multiparking/channels/chan_sip.c Sun Mar 9 08:48:27 2008
@@ -3388,6 +3388,7 @@
{
char multi[256];
char *stringp, *ext, *context;
+ struct pbx_find_info q = { .stacklen = 0 };
/* XXX note that global_regcontext is both a global 'enable' flag and
* the name of the global regexten context, if not specified
@@ -3408,11 +3409,12 @@
} else {
context = global_regcontext;
}
- if (onoff)
+ if (onoff) {
ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
ast_strdup(peer->name), ast_free_ptr, "SIP");
- else
+ } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) {
ast_context_remove_extension(context, ext, 1, NULL);
+ }
}
}
@@ -20297,8 +20299,7 @@
/* Create contexts if they don't exist already */
while ((context = strsep(&stringp, "&"))) {
ast_copy_string(used_context, context, sizeof(used_context));
- if (!ast_context_find(context))
- ast_context_create(NULL, context, "SIP");
+ ast_context_find_or_create(NULL, NULL, context, "SIP");
}
ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
} else if (!strcasecmp(v->name, "regextenonqualify")) {
Modified: team/group/multiparking/channels/chan_skinny.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/channels/chan_skinny.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/channels/chan_skinny.c (original)
+++ team/group/multiparking/channels/chan_skinny.c Sun Mar 9 08:48:27 2008
@@ -5801,8 +5801,7 @@
/* Create contexts if they don't exist already */
while ((context = strsep(&stringp, "&"))) {
ast_copy_string(used_context, context, sizeof(used_context));
- if (!ast_context_find(context))
- ast_context_create(NULL, context, "Skinny");
+ ast_context_find_or_create(NULL, NULL, context, "Skinny");
}
ast_copy_string(regcontext, v->value, sizeof(regcontext));
} else if (!strcasecmp(v->name, "dateformat")) {
Modified: team/group/multiparking/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/channels/chan_zap.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/channels/chan_zap.c (original)
+++ team/group/multiparking/channels/chan_zap.c Sun Mar 9 08:48:27 2008
@@ -9514,9 +9514,11 @@
}
p = linkset->pvts[chanpos];
- zt_loopback(p, 0);
-
- ss7_start_call(p, linkset);
+ if (p->loopedback) {
+ zt_loopback(p, 0);
+ ss7_start_call(p, linkset);
+ }
+
break;
case ISUP_EVENT_CCR:
ast_debug(1, "Got CCR request on CIC %d\n", e->ccr.cic);
@@ -10307,8 +10309,18 @@
if (e) {
if (pri->debug)
pri_dump_event(pri->dchans[which], e);
- if (e->e != PRI_EVENT_DCHAN_DOWN)
+
+ if (e->e != PRI_EVENT_DCHAN_DOWN) {
+ if (!(pri->dchanavail[which] & DCHAN_UP)) {
+ ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
+ }
pri->dchanavail[which] |= DCHAN_UP;
+ } else {
+ if (pri->dchanavail[which] & DCHAN_UP) {
+ ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
+ }
+ pri->dchanavail[which] &= ~DCHAN_UP;
+ }
if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
/* Must be an NFAS group that has the secondary dchan active */
@@ -10316,8 +10328,6 @@
switch (e->e) {
case PRI_EVENT_DCHAN_UP:
- ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
- pri->dchanavail[which] |= DCHAN_UP;
if (!pri->pri) pri_find_dchan(pri);
/* Note presense of D-channel */
@@ -10336,8 +10346,6 @@
}
break;
case PRI_EVENT_DCHAN_DOWN:
- ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
- pri->dchanavail[which] &= ~DCHAN_UP;
pri_find_dchan(pri);
if (!pri_is_up(pri)) {
pri->resetting = 0;
Modified: team/group/multiparking/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/include/asterisk/pbx.h?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/include/asterisk/pbx.h (original)
+++ team/group/multiparking/include/asterisk/pbx.h Sun Mar 9 08:48:27 2008
@@ -25,6 +25,7 @@
#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
+#include "asterisk/hashtab.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
@@ -167,11 +168,16 @@
int pbx_exec(struct ast_channel *c, struct ast_app *app, void *data);
/*!
- * \brief Register a new context
+ * \brief Register a new context or find an existing one
*
* \param extcontexts pointer to the ast_context structure pointer
+ * \param exttable pointer to the hashtable that contains all the elements in extcontexts
* \param name name of the new context
* \param registrar registrar of the context
+ *
+ * This function allows you to play in two environments: the global contexts (active dialplan)
+ * or an external context set of your choosing. To act on the external set, make sure extcontexts
+ * and exttable are set; for the globals, make sure both extcontexts and exttable are NULL.
*
* This will first search for a context with your name. If it exists already, it will not
* create a new one. If it does not exist, it will create a new one with the given name
@@ -179,33 +185,19 @@
*
* \return NULL on failure, and an ast_context structure on success
*/
-struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar);
-
-/*!
- * \brief Register a new context or find an existing one
- *
- * \param extcontexts pointer to the ast_context structure pointer
- * \param name name of the new context
- * \param registrar registrar of the context
- *
- * This will first search for a context with your name. If it exists already, it will not
- * create a new one. If it does not exist, it will create a new one with the given name
- * and registrar.
- *
- * \return NULL on failure, and an ast_context structure on success
- */
-struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, const char *name, const char *registrar);
+struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar);
/*!
* \brief Merge the temporary contexts into a global contexts list and delete from the
* global list the ones that are being added
*
- * \param extcontexts pointer to the ast_context structure pointer
+ * \param extcontexts pointer to the ast_context structure
+ * \param exttable pointer to the ast_hashtab structure that contains all the elements in extcontexts
* \param registrar of the context; if it's set the routine will delete all contexts
* that belong to that registrar; if NULL only the contexts that are specified
* in extcontexts
*/
-void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
+void ast_merge_contexts_and_delete(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar);
/*!
* \brief Destroy a context (matches the specified context (or ANY context if NULL)
@@ -973,8 +965,18 @@
struct ast_context *bypass, struct pbx_find_info *q,
const char *context, const char *exten, int priority,
const char *label, const char *callerid, enum ext_match_t action);
+
+
+/* every time a write lock is obtained for contexts,
+ a counter is incremented. You can check this via the
+ following func */
+
+int ast_wrlock_contexts_version(void);
+/* hashtable functions for contexts */
+int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b);
+unsigned int ast_hashtab_hash_contexts(const void *obj);
#if defined(__cplusplus) || defined(c_plusplus)
}
Modified: team/group/multiparking/include/asterisk/pval.h
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/include/asterisk/pval.h?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/include/asterisk/pval.h (original)
+++ team/group/multiparking/include/asterisk/pval.h Sun Mar 9 08:48:27 2008
@@ -1,6 +1,7 @@
#ifndef _ASTERISK_PVAL_H
#define _ASTERISK_PVAL_H
+/* whatever includes this, better include asterisk/lock.h and asterisk/hashtab.h */
typedef enum
{
@@ -143,7 +144,7 @@
static void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *context ); */
void set_priorities(struct ael_extension *exten);
void add_extensions(struct ael_extension *exten);
-void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root);
+void ast_compile_ael2(struct ast_context **local_contexts, struct ast_hashtab *local_table, struct pval *root);
void destroy_pval(pval *item);
void destroy_pval_item(pval *item);
int is_float(char *arg );
Modified: team/group/multiparking/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/main/channel.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/main/channel.c (original)
+++ team/group/multiparking/main/channel.c Sun Mar 9 08:48:27 2008
@@ -2203,6 +2203,7 @@
return -1;
case AST_CONTROL_RINGING:
case AST_CONTROL_ANSWER:
+ case AST_CONTROL_SRCUPDATE:
/* Unimportant */
break;
default:
Modified: team/group/multiparking/main/editline/Makefile.in
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/main/editline/Makefile.in?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/main/editline/Makefile.in (original)
+++ team/group/multiparking/main/editline/Makefile.in Sun Mar 9 08:48:27 2008
@@ -4,7 +4,7 @@
OSTYPE=$(shell uname -s)
define cyg_subst_sys
- if uname -s | grep -qi cygwin; then \
+ if uname -s | ${GREP} -qi cygwin; then \
cat $@ | sed -e s/"sys\.h"/"config.h"/g > $@.copy; \
mv --force $@.copy $@; \
fi
Modified: team/group/multiparking/main/features.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/main/features.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/main/features.c (original)
+++ team/group/multiparking/main/features.c Sun Mar 9 08:48:27 2008
@@ -567,9 +567,7 @@
ast_adsi_unload_session(peer);
}
- con = ast_context_find(parkinglot->parking_con);
- if (!con)
- con = ast_context_create(NULL, parkinglot->parking_con, registrar);
+ con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar);
if (!con) /* Still no context? Bad */
ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
/* Tell the peer channel the number of the parking space */
@@ -2299,11 +2297,9 @@
if (peername_flat[i] == '/')
peername_flat[i]= '0';
}
- con = ast_context_find(pu->parkinglot->parking_con_dial);
+ con = ast_context_find_or_create(NULL, NULL, pu->parkinglot->parking_con_dial, registrar);
if (!con) {
- con = ast_context_create(NULL, pu->parkinglot->parking_con_dial, registrar);
- if (!con)
- ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
+ ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", pu->parkinglot->parking_con_dial);
}
if (con) {
char returnexten[AST_MAX_EXTENSION];
@@ -2772,11 +2768,9 @@
}
/* Create context */
- if (!error && !(con = ast_context_find(parkinglot->parking_con))) {
- if (!(con = ast_context_create(NULL, parkinglot->parking_con, registrar))) {
- ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
- error = 1;
- }
+ if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar))) {
+ ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
+ error = 1;
}
/* Add a parking extension into the context */
@@ -3123,11 +3117,9 @@
ast_debug(1, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
}
- if (!(con = ast_context_find(default_parkinglot->parking_con))) {
- if (!(con = ast_context_create(NULL, default_parkinglot->parking_con, registrar))) {
- ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", default_parkinglot->parking_con);
- return -1;
- }
+ if (!(con = ast_context_find_or_create(NULL, NULL, default_parkinglot->parking_con, registrar))) {
+ ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", default_parkinglot->parking_con);
+ return -1;
}
res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, NULL, NULL, registrar);
if (parkaddhints)
Modified: team/group/multiparking/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/main/pbx.c?view=diff&rev=107013&r1=107012&r2=107013
==============================================================================
--- team/group/multiparking/main/pbx.c (original)
+++ team/group/multiparking/main/pbx.c Sun Mar 9 08:48:27 2008
@@ -48,6 +48,7 @@
#include "asterisk/cdr.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
+#include "asterisk/time.h"
#include "asterisk/manager.h"
#include "asterisk/ast_expr.h"
#include "asterisk/linkedlists.h"
@@ -140,8 +141,8 @@
void *data; /*!< Data to use (arguments) */
void (*datad)(void *); /*!< Data destructor */
struct ast_exten *peer; /*!< Next higher priority with our extension */
- struct ast_hashtab *peer_tree; /*!< Priorities list in tree form -- only on the head of the peer list */
- struct ast_hashtab *peer_label_tree; /*!< labeled priorities in the peer list -- only on the head of the peer list */
+ struct ast_hashtab *peer_table; /*!< Priorities list in hashtab form -- only on the head of the peer list */
+ struct ast_hashtab *peer_label_table; /*!< labeled priorities in the peers -- only on the head of the peer list */
const char *registrar; /*!< Registrar */
struct ast_exten *next; /*!< Extension with a greater ID */
char stuff[0];
@@ -203,12 +204,13 @@
struct ast_context {
ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
struct ast_exten *root; /*!< The root of the list of extensions */
- struct ast_hashtab *root_tree; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */
+ struct ast_hashtab *root_table; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */
struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
struct ast_context *next; /*!< Link them together */
struct ast_include *includes; /*!< Include other contexts */
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
const char *registrar; /*!< Registrar */
+ int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */
AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
char name[0]; /*!< Name of the context */
@@ -327,17 +329,18 @@
static void create_match_char_tree(struct ast_context *con);
static struct ast_exten *get_canmatch_exten(struct match_char *node);
static void destroy_pattern_tree(struct match_char *pattern_tree);
-static int hashtab_compare_contexts(const void *ah_a, const void *ah_b);
+int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b);
static int hashtab_compare_extens(const void *ha_a, const void *ah_b);
static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b);
static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b);
-static unsigned int hashtab_hash_contexts(const void *obj);
+unsigned int ast_hashtab_hash_contexts(const void *obj);
static unsigned int hashtab_hash_extens(const void *obj);
static unsigned int hashtab_hash_priority(const void *obj);
static unsigned int hashtab_hash_labels(const void *obj);
+static void __ast_internal_context_destroy( struct ast_context *con);
/* labels, contexts are case sensitive priority numbers are ints */
-static int hashtab_compare_contexts(const void *ah_a, const void *ah_b)
+int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
{
const struct ast_context *ac = ah_a;
const struct ast_context *bc = ah_b;
@@ -376,7 +379,7 @@
return strcmp(ac->label, bc->label);
}
-static unsigned int hashtab_hash_contexts(const void *obj)
+unsigned int ast_hashtab_hash_contexts(const void *obj)
{
const struct ast_context *ac = obj;
return ast_hashtab_hash_string(ac->name);
@@ -684,7 +687,7 @@
};
static struct ast_context *contexts;
-static struct ast_hashtab *contexts_tree = NULL;
+static struct ast_hashtab *contexts_table = NULL;
AST_RWLOCK_DEFINE_STATIC(conlock); /*!< Lock for the ast_context list */
@@ -1252,11 +1255,11 @@
int biggest_bucket, resizes, numobjs, numbucks;
ast_log(LOG_DEBUG,"Creating Extension Trie for context %s\n", con->name);
- ast_hashtab_get_stats(con->root_tree, &biggest_bucket, &resizes, &numobjs, &numbucks);
+ ast_hashtab_get_stats(con->root_table, &biggest_bucket, &resizes, &numobjs, &numbucks);
ast_log(LOG_DEBUG,"This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
numobjs, numbucks, biggest_bucket, resizes);
#endif
- t1 = ast_hashtab_start_traversal(con->root_tree);
+ t1 = ast_hashtab_start_traversal(con->root_table);
while( (e1 = ast_hashtab_next(t1)) ) {
if (e1->exten)
add_exten_to_pattern_tree(con, e1, 0);
@@ -1582,12 +1585,13 @@
{
ast_rwlock_t lock;
struct ast_exten *root;
- struct ast_hashtab *root_tree;
+ struct ast_hashtab *root_table;
struct match_char *pattern_tree;
struct ast_context *next;
struct ast_include *includes;
struct ast_ignorepat *ignorepats;
- const char *registrar;
+ const char *registrar;
+ int refcount;
AST_LIST_HEAD_NOLOCK(, ast_sw) alts;
ast_mutex_t macrolock;
char name[256];
@@ -1599,8 +1603,8 @@
struct fake_context item;
strncpy(item.name,name,256);
ast_rdlock_contexts();
- if( contexts_tree ) {
- tmp = ast_hashtab_lookup(contexts_tree,&item);
+ if( contexts_table ) {
+ tmp = ast_hashtab_lookup(contexts_table,&item);
} else {
while ( (tmp = ast_walk_contexts(tmp)) ) {
if (!name || !strcasecmp(name, tmp->name))
@@ -1668,7 +1672,7 @@
else { /* look in contexts */
struct fake_context item;
strncpy(item.name,context,256);
- tmp = ast_hashtab_lookup(contexts_tree,&item);
+ tmp = ast_hashtab_lookup(contexts_table,&item);
#ifdef NOTNOW
tmp = NULL;
while ((tmp = ast_walk_contexts(tmp)) ) {
@@ -1690,7 +1694,7 @@
score.total_specificity = 0;
score.exten = 0;
score.total_length = 0;
- if (!tmp->pattern_tree && tmp->root_tree)
+ if (!tmp->pattern_tree && tmp->root_table)
{
create_match_char_tree(tmp);
#ifdef NEED_DEBUG
@@ -1750,9 +1754,9 @@
if (action == E_FINDLABEL && label ) {
if (q->status < STATUS_NO_LABEL)
q->status = STATUS_NO_LABEL;
- e = ast_hashtab_lookup(eroot->peer_label_tree, &pattern);
+ e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
} else {
- e = ast_hashtab_lookup(eroot->peer_tree, &pattern);
+ e = ast_hashtab_lookup(eroot->peer_table, &pattern);
}
if (e) { /* found a valid match */
q->status = STATUS_SUCCESS;
@@ -1786,9 +1790,9 @@
if (action == E_FINDLABEL && label ) {
if (q->status < STATUS_NO_LABEL)
q->status = STATUS_NO_LABEL;
- e = ast_hashtab_lookup(eroot->peer_label_tree, &pattern);
+ e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
} else {
- e = ast_hashtab_lookup(eroot->peer_tree, &pattern);
+ e = ast_hashtab_lookup(eroot->peer_table, &pattern);
}
#ifdef NOTNOW
while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
@@ -2465,7 +2469,7 @@
vare++;
}
if (brackets)
- ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
+ ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n");
len = vare - vars - 1;
/* Skip totally over variable string */
@@ -2552,7 +2556,7 @@
vare++;
}
if (brackets)
- ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
+ ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n");
len = vare - vars - 1;
/* Skip totally over expression */
@@ -3479,14 +3483,14 @@
ast_mutex_lock(&maxcalllock);
if (option_maxcalls) {
if (countcalls >= option_maxcalls) {
- ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
+ ast_log(LOG_WARNING, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
failed = -1;
}
}
if (option_maxload) {
getloadavg(&curloadavg, 1);
if (curloadavg >= option_maxload) {
- ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
+ ast_log(LOG_WARNING, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
failed = -1;
}
}
@@ -3527,10 +3531,10 @@
if (e->priority == PRIORITY_HINT)
ast_remove_hint(e);
- if (e->peer_tree)
- ast_hashtab_destroy(e->peer_tree,0);
- if (e->peer_label_tree)
- ast_hashtab_destroy(e->peer_label_tree, 0);
+ if (e->peer_table)
+ ast_hashtab_destroy(e->peer_table,0);
+ if (e->peer_label_table)
+ ast_hashtab_destroy(e->peer_label_table, 0);
if (e->datad)
e->datad(e->data);
ast_free(e);
@@ -3627,8 +3631,7 @@
ast_copy_string(item.name, context, sizeof(item.name));
ast_rdlock_contexts();
-
- c = ast_hashtab_lookup(contexts_tree,&item);
+ c = ast_hashtab_lookup(contexts_table,&item);
#ifdef NOTNOW
@@ -3789,19 +3792,19 @@
/* Handle this is in the new world */
#ifdef NEED_DEBUG
- ast_log(LOG_NOTICE,"Removing %s/%s/%d from trees, registrar=%s\n", con->name, extension, priority, registrar);
+ ast_verb(3,"Removing %s/%s/%d from trees, registrar=%s\n", con->name, extension, priority, registrar);
#endif
/* find this particular extension */
ex.exten = dummy_name;
ex.matchcid = 0;
ast_copy_string(dummy_name,extension, sizeof(dummy_name));
- exten = ast_hashtab_lookup(con->root_tree, &ex);
+ exten = ast_hashtab_lookup(con->root_table, &ex);
if (exten) {
if (priority == 0)
{
- exten2 = ast_hashtab_remove_this_object(con->root_tree, exten);
+ exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
if (!exten2)
- ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_tree\n", extension, con->name);
+ ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_table\n", extension, con->name);
if (con->pattern_tree) {
struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
@@ -3815,24 +3818,28 @@
}
} else {
ex.priority = priority;
- exten2 = ast_hashtab_lookup(exten->peer_tree, &ex);
+ exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
if (exten2) {
if (exten2->label) { /* if this exten has a label, remove that, too */
- exten3 = ast_hashtab_remove_this_object(exten->peer_label_tree,exten2);
+ exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
if (!exten3)
- ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_tree of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
+ ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_table of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
}
- exten3 = ast_hashtab_remove_this_object(exten->peer_tree, exten2);
+ exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
if (!exten3)
- ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_tree of context %s, extension %s!\n", priority, con->name, exten2->exten);
- if (ast_hashtab_size(exten->peer_tree) == 0) {
+ ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_table of context %s, extension %s!\n", priority, con->name, exten2->exten);
+ if (exten2 == exten && exten2->peer) {
+ exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
+ ast_hashtab_insert_immediate(con->root_table, exten2->peer);
+ }
+ if (ast_hashtab_size(exten->peer_table) == 0) {
/* well, if the last priority of an exten is to be removed,
then, the extension is removed, too! */
- exten3 = ast_hashtab_remove_this_object(con->root_tree, exten);
+ exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
if (!exten3)
- ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_tree (%s) (priority %d)\n", exten->exten, con->name, priority);
+ ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority);
if (con->pattern_tree) {
struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
if (x->exten) { /* this test for safety purposes */
@@ -3848,7 +3855,7 @@
}
} else {
/* hmmm? this exten is not in this pattern tree? */
- ast_log(LOG_WARNING,"Cannot find extension %s in root_tree in context %s\n",
+ ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
extension, con->name);
}
#ifdef NEED_DEBUG
@@ -3905,10 +3912,10 @@
*/
struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
if (next_node && next_node == peer->peer) {
- next_node->peer_tree = exten->peer_tree; /* move the priority hash tabs over */
- exten->peer_tree = 0;
- next_node->peer_label_tree = exten->peer_label_tree;
- exten->peer_label_tree = 0;
+ next_node->peer_table = exten->peer_table; /* move the priority hash tabs over */
+ exten->peer_table = 0;
+ next_node->peer_label_table = exten->peer_label_table;
+ exten->peer_label_table = 0;
}
if (!prev_exten) { /* change the root... */
con->root = next_node;
@@ -3946,7 +3953,7 @@
ast_rdlock_contexts();
strncpy(item.name,context,256);
- c = ast_hashtab_lookup(contexts_tree,&item);
+ c = ast_hashtab_lookup(contexts_table,&item);
if (c)
ret = 0;
@@ -3984,7 +3991,7 @@
ast_rdlock_contexts();
strncpy(item.name, context, 256);
- c = ast_hashtab_lookup(contexts_tree,&item);
+ c = ast_hashtab_lookup(contexts_table,&item);
if (c)
ret = 0;
#ifdef NOTNOW
@@ -4578,7 +4585,7 @@
if (exten) {
/* Check all includes for the requested extension */
if (includecount >= AST_PBX_MAX_STACK) {
- ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n");
+ ast_log(LOG_WARNING, "Maximum include depth exceeded!\n");
} else {
int dupe = 0;
int x;
@@ -5127,42 +5134,37 @@
return tmp ? 0 : -1;
}
-static struct ast_context *__ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
+struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
{
struct ast_context *tmp, **local_contexts;
struct fake_context search;
int length = sizeof(struct ast_context) + strlen(name) + 1;
- if (!contexts_tree) {
- contexts_tree = ast_hashtab_create(17,
- hashtab_compare_contexts,
+ if (!contexts_table) {
+ contexts_table = ast_hashtab_create(17,
+ ast_hashtab_compare_contexts,
ast_hashtab_resize_java,
ast_hashtab_newsize_java,
- hashtab_hash_contexts,
+ ast_hashtab_hash_contexts,
0);
}
+ strncpy(search.name,name,sizeof(search.name));
if (!extcontexts) {
ast_rdlock_contexts();
local_contexts = &contexts;
- strncpy(search.name,name,sizeof(search.name));
- tmp = ast_hashtab_lookup(contexts_tree, &search);
- if (!existsokay && tmp) {
- ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
- }
+ tmp = ast_hashtab_lookup(contexts_table, &search);
ast_unlock_contexts();
- if (tmp)
+ if (tmp) {
+ tmp->refcount++;
return tmp;
+ }
} else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
local_contexts = extcontexts;
- for (tmp = *local_contexts; tmp; tmp = tmp->next) {
- if (!strcasecmp(tmp->name, name)) {
- if (!existsokay) {
- ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
- tmp = NULL;
- }
- return tmp;
- }
+ tmp = ast_hashtab_lookup(exttable, &search);
+ if (tmp) {
+ tmp->refcount++;
+ return tmp;
}
}
@@ -5171,19 +5173,26 @@
ast_mutex_init(&tmp->macrolock);
strcpy(tmp->name, name);
tmp->root = NULL;
- tmp->root_tree = NULL;
+ tmp->root_table = NULL;
tmp->registrar = registrar;
tmp->includes = NULL;
tmp->ignorepats = NULL;
- }
+ tmp->refcount = 1;
+ } else {
+ ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
+ return NULL;
+ }
+
if (!extcontexts) {
ast_wrlock_contexts();
tmp->next = *local_contexts;
*local_contexts = tmp;
- ast_hashtab_insert_safe(contexts_tree, tmp); /*put this context into the tree */
+ ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
ast_unlock_contexts();
} else {
tmp->next = *local_contexts;
+ if (exttable)
+ ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
*local_contexts = tmp;
}
ast_debug(1, "Registered context '%s'\n", tmp->name);
@@ -5191,16 +5200,7 @@
return tmp;
}
-struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar)
-{
- return __ast_context_create(extcontexts, name, registrar, 0);
-}
-
-struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, const char *name, const char *registrar)
-{
- return __ast_context_create(extcontexts, name, registrar, 1);
-}
-void __ast_context_destroy(struct ast_context *con, const char *registrar);
+void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *contexttab, struct ast_context *con, const char *registrar);
struct store_hint {
char *context;
@@ -5213,17 +5213,89 @@
AST_LIST_HEAD(store_hints, store_hint);
+/* the purpose of this routine is to duplicate a context, with all its substructure,
+ except for any extens that have a matching registrar */
+static void context_merge(struct ast_context **extcontexts, struct ast_hashtab *exttable, struct ast_context *context, const char *registrar)
+{
+ struct ast_context *new = ast_hashtab_lookup(exttable, context); /* is there a match in the new set? */
+ struct ast_exten *exten_item, *prio_item, *new_exten_item, *new_prio_item;
+ struct ast_hashtab_iter *exten_iter;
+ struct ast_hashtab_iter *prio_iter;
+ int insert_count = 0;
+
+ /* We'll traverse all the extensions/prios, and see which are not registrar'd with
+ the current registrar, and copy them to the new context. If the new context does not
+ exist, we'll create it "on demand". If no items are in this context to copy, then we'll
+ only create the empty matching context if the old one meets the criteria */
+ if (context->root_table) {
+ exten_iter = ast_hashtab_start_traversal(context->root_table);
+ while ((exten_item=ast_hashtab_next(exten_iter))) {
+ if (new) {
+ new_exten_item = ast_hashtab_lookup(new->root_table, exten_item);
+ } else {
+ new_exten_item = NULL;
+ }
+ prio_iter = ast_hashtab_start_traversal(exten_item->peer_table);
+ while ((prio_item=ast_hashtab_next(prio_iter))) {
+ int res1;
+
+ if (new_exten_item) {
+ new_prio_item = ast_hashtab_lookup(new_exten_item->peer_table, prio_item);
+ } else {
+ new_prio_item = NULL;
+ }
+ if (strcmp(prio_item->registrar,registrar) == 0) {
+ continue;
+ }
+ /* make sure the new context exists, so we have somewhere to stick this exten/prio */
+ if (!new) {
+ new = ast_context_find_or_create(extcontexts, exttable, context->name, prio_item->registrar); /* a new context created via priority from a different context in the old dialplan, gets its registrar from the prio's registrar */
+ }
+ if (!new) {
+ ast_log(LOG_ERROR,"Could not allocate a new context for %s in merge_and_delete! Danger!\n", context->name);
+ return; /* no sense continuing. */
+ }
+ /* we will not replace existing entries in the new context with stuff from the old context.
[... 4485 lines stripped ...]
More information about the svn-commits
mailing list