ao2_unlock(trunk);
if (!ast_strlen_zero(trunk->autocontext)) {
- struct ast_context *context;
- context = ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar);
- if (!context) {
+ if (!ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically find or create "
"context '%s' for SLA!\n", trunk->autocontext);
return -1;
}
- if (ast_add_extension2(context, 0 /* don't replace */, "s", 1,
+
+ if (ast_add_extension(trunk->autocontext, 0 /* don't replace */, "s", 1,
NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free_ptr, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create extension "
"for trunk '%s'!\n", trunk->name);
ao2_unlock(station);
if (!ast_strlen_zero(station->autocontext)) {
- struct ast_context *context;
struct sla_trunk_ref *trunk_ref;
- context = ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar);
- if (!context) {
+
+ if (!ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically find or create "
"context '%s' for SLA!\n", station->autocontext);
return -1;
}
/* The extension for when the handset goes off-hook.
* exten => station1,1,SLAStation(station1) */
- if (ast_add_extension2(context, 0 /* don't replace */, station->name, 1,
+ if (ast_add_extension(station->autocontext, 0 /* don't replace */, station->name, 1,
NULL, NULL, slastation_app, ast_strdup(station->name), ast_free_ptr, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create extension "
"for trunk '%s'!\n", station->name);
snprintf(hint, sizeof(hint), "SLA:%s", exten);
/* Extension for this line button
* exten => station1_line1,1,SLAStation(station1_line1) */
- if (ast_add_extension2(context, 0 /* don't replace */, exten, 1,
+ if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, 1,
NULL, NULL, slastation_app, ast_strdup(exten), ast_free_ptr, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create extension "
"for trunk '%s'!\n", station->name);
}
/* Hint for this line button
* exten => station1_line1,hint,SLA:station1_line1 */
- if (ast_add_extension2(context, 0 /* don't replace */, exten, PRIORITY_HINT,
+ if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, PRIORITY_HINT,
NULL, NULL, hint, NULL, NULL, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create hint "
"for trunk '%s'!\n", station->name);
static int __unload_module(void)
{
- struct ast_context *con;
int x;
network_change_event_unsubscribe();
ao2_ref(callno_pool, -1);
ao2_ref(callno_pool_trunk, -1);
- con = ast_context_find(regcontext);
- if (con)
- ast_context_destroy(con, "IAX2");
+ ast_context_destroy_by_name(regcontext, "IAX2");
ast_unload_realtime("iaxpeers");
iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
}
}
- if (stalecontext)
- ast_context_destroy(ast_context_find(stalecontext), "SIP");
+ ast_context_destroy_by_name(stalecontext, "SIP");
}
}
{
struct sip_pvt *p;
struct sip_threadinfo *th;
- struct ast_context *con;
struct ao2_iterator i;
int wait_count;
close(sipsock);
io_context_destroy(io);
ast_sched_context_destroy(sched);
- con = ast_context_find(used_context);
- if (con) {
- ast_context_destroy(con, "SIP");
- }
+ ast_context_destroy_by_name(used_context, "SIP");
ast_unload_realtime("sipregs");
ast_unload_realtime("sippeers");
ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
}
}
- if (stalecontext)
- ast_context_destroy(ast_context_find(stalecontext), "Skinny");
+ ast_context_destroy_by_name(stalecontext, "Skinny");
}
}
struct skinny_device *d;
struct skinny_line *l;
struct skinny_subchannel *sub;
- struct ast_context *con;
ast_rtp_glue_unregister(&skinny_rtp_glue);
ast_channel_unregister(&skinny_tech);
ast_sched_context_destroy(sched);
}
- con = ast_context_find(used_context);
- if (con)
- ast_context_destroy(con, "Skinny");
+ ast_context_destroy_by_name(used_context, "Skinny");
default_cap = ast_format_cap_destroy(default_cap);
skinny_tech.capabilities = ast_format_cap_destroy(skinny_tech.capabilities);
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)
+ * \brief Destroy a context by name
+ *
+ * \param context Name of the context to destroy
+ * \param registrar who registered it
+ *
+ * You can optionally leave out the registrar parameter. It will find it
+ * based on the context name.
+ *
+ * \retval -1 context not found
+ * \retval 0 Success
+ */
+int ast_context_destroy_by_name(const char *context, const char *registrar);
+
+/*!
+ * \brief Destroy a context (matches the specified context or ANY context if NULL)
*
* \param con context to destroy
* \param registrar who registered it
}
if (manage_parked_call(pu, pfds, nfds, new_pfds, new_nfds, ms)) {
/* Parking is complete for this call so remove it from the parking lot. */
+ ast_wrlock_contexts();
con = ast_context_find(pu->parkinglot->cfg.parking_con);
if (con) {
if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0)) {
"Whoa, failed to remove the parking extension %s@%s!\n",
pu->parkingexten, pu->parkinglot->cfg.parking_con);
}
+ }
+ ast_unlock_contexts();
+ if (con) {
notify_metermaids(pu->parkingexten, pu->parkinglot->cfg.parking_con,
AST_DEVICE_NOT_INUSE);
} else {
/*! \brief Pickup parked call */
static int parked_call_exec(struct ast_channel *chan, const char *data)
{
- int res;
+ int res = 0;
struct ast_channel *peer = NULL;
struct parkeduser *pu;
struct ast_context *con;
callid = ast_callid_unref(callid);
}
+ ast_wrlock_contexts();
con = ast_context_find(parkinglot->cfg.parking_con);
if (con) {
- if (ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 0)) {
+ res = ast_context_remove_extension2(con, pu->parkingexten, 1, NULL, 1);
+ }
+ ast_unlock_contexts();
+
+ if (con) {
+ if (res) {
ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
} else {
notify_metermaids(pu->parkingexten, parkinglot->cfg.parking_con, AST_DEVICE_NOT_INUSE);
{
struct parking_dp_context *old_ctx;
struct parking_dp_context *new_ctx;
- struct ast_context *con;
int cmp;
old_ctx = AST_LIST_FIRST(old_map);
cmp = strcmp(old_ctx->context, new_ctx->context);
if (cmp < 0) {
/* New map does not have old map context. */
- con = ast_context_find(old_ctx->context);
- if (con) {
- ast_context_destroy(con, registrar);
- }
+ ast_context_destroy_by_name(old_ctx->context, registrar);
old_ctx = AST_LIST_NEXT(old_ctx, node);
continue;
}
/* Any old contexts left must be dead. */
for (; old_ctx; old_ctx = AST_LIST_NEXT(old_ctx, node)) {
- con = ast_context_find(old_ctx->context);
- if (con) {
- ast_context_destroy(con, registrar);
- }
+ ast_context_destroy_by_name(old_ctx->context, registrar);
}
}
int ast_features_reload(void)
{
- struct ast_context *con;
int res;
ast_mutex_lock(&features_reload_lock);/* Searialize reloading features.conf */
* extension. This is a small window of opportunity on an
* execution chain that is not expected to happen very often.
*/
- con = ast_context_find(parking_con_dial);
- if (con) {
- ast_context_destroy(con, registrar);
- }
+ ast_context_destroy_by_name(parking_con_dial, registrar);
res = load_config(1);
ast_mutex_unlock(&features_reload_lock);
return -1;
}
+ ast_wrlock_contexts();
con = ast_context_find(args->pu->parkinglot->cfg.parking_con);
if (con) {
- if (ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 0)) {
+ res = ast_context_remove_extension2(con, args->pu->parkingexten, 1, NULL, 1);
+ }
+ ast_unlock_contexts();
+
+ if (con) {
+ if (res) {
ast_log(LOG_WARNING, "Whoa, failed to remove the parking extension!\n");
res = -1;
} else {
ast_rdlock_contexts();
local_contexts = &contexts;
tmp = ast_hashtab_lookup(contexts_table, &search);
- ast_unlock_contexts();
if (tmp) {
tmp->refcount++;
+ ast_unlock_contexts();
return tmp;
}
} else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
tmp->refcount = 1;
} else {
ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
+ if (!extcontexts) {
+ ast_unlock_contexts();
+ }
return NULL;
}
if (!extcontexts) {
- ast_wrlock_contexts();
tmp->next = *local_contexts;
*local_contexts = tmp;
ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
int ast_ignore_pattern(const char *context, const char *pattern)
{
- struct ast_context *con = ast_context_find(context);
+ int ret = 0;
+ struct ast_context *con;
+ ast_rdlock_contexts();
+ con = ast_context_find(context);
if (con) {
struct ast_ignorepat *pat;
for (pat = con->ignorepats; pat; pat = pat->next) {
- if (ast_extension_match(pat->pattern, pattern))
- return 1;
+ if (ast_extension_match(pat->pattern, pattern)) {
+ ret = 1;
+ break;
+ }
}
}
+ ast_unlock_contexts();
- return 0;
+ return ret;
}
/*
}
}
+int ast_context_destroy_by_name(const char *context, const char *registrar)
+{
+ struct ast_context *con;
+ int ret = -1;
+
+ ast_wrlock_contexts();
+ con = ast_context_find(context);
+ if (con) {
+ ast_context_destroy(con, registrar);
+ ret = 0;
+ }
+ ast_unlock_contexts();
+
+ return ret;
+}
+
void ast_context_destroy(struct ast_context *con, const char *registrar)
{
ast_wrlock_contexts();
static char *handle_cli_dialplan_remove_context(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct ast_context *con;
-
switch (cmd) {
case CLI_INIT:
e->command = "dialplan remove context";
return CLI_SHOWUSAGE;
}
- con = ast_context_find(a->argv[3]);
-
- if (!con) {
- ast_cli(a->fd, "There is no such context as '%s'\n",
- a->argv[3]);
- return CLI_SUCCESS;
+ if (ast_context_destroy_by_name(a->argv[3], NULL)) {
+ ast_cli(a->fd, "There is no such context as '%s'\n", a->argv[3]);
+ return CLI_SUCCESS;
} else {
- ast_context_destroy(con, registrar);
- ast_cli(a->fd, "Removing context '%s'\n",
- a->argv[3]);
+ ast_cli(a->fd, "Removed context '%s'\n", a->argv[3]);
return CLI_SUCCESS;
}
}
AST_TEST_DEFINE(test_gosub)
{
+#define CONTEXT_NAME "tests_test_gosub_virtual_context"
int res = AST_TEST_PASS, i;
struct ast_channel *chan;
struct ast_str *str;
- struct ast_context *con;
struct testplan {
const char *app;
const char *args;
}
/* Create our test dialplan */
- if (!(con = ast_context_find_or_create(NULL, NULL, "tests_test_gosub_virtual_context", "test_gosub"))) {
+ if (!ast_context_find_or_create(NULL, NULL, CONTEXT_NAME, "test_gosub")) {
ast_test_status_update(test, "Unable to create test dialplan context");
ast_free(str);
ast_channel_unref(chan);
return AST_TEST_FAIL;
}
- ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "test_gosub");
+ ast_add_extension(CONTEXT_NAME, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "test_gosub");
for (i = 0; i < ARRAY_LEN(testplan); i++) {
if (testplan[i].app == NULL) {
ast_free(str);
ast_channel_unref(chan);
- ast_context_remove_extension2(con, "s", 1, NULL, 0);
- ast_context_destroy(con, "test_gosub");
+ ast_context_remove_extension(CONTEXT_NAME, "s", 1, NULL);
+ ast_context_destroy(NULL, "test_gosub");
return res;
}
*/
struct {
const char * context_string;
- struct ast_context *context;
} contexts[] = {
{ TEST_PATTERN, },
{ TEST_PATTERN_INCLUDE, },
*/
for (i = 0; i < ARRAY_LEN(contexts); ++i) {
- if (!(contexts[i].context = ast_context_find_or_create(NULL, NULL, contexts[i].context_string, registrar))) {
+ if (!ast_context_find_or_create(NULL, NULL, contexts[i].context_string, registrar)) {
ast_test_status_update(test, "Failed to create context %s\n", contexts[i].context_string);
res = AST_TEST_FAIL;
goto cleanup;
}
cleanup:
- for (i = 0; i < ARRAY_LEN(contexts); ++i) {
- if (contexts[i].context) {
- ast_context_destroy(contexts[i].context, registrar);
- }
- }
+ ast_context_destroy(NULL, registrar);
return res;
}