diff options
author | Steve Murphy <murf@digium.com> | 2008-06-16 20:43:46 +0000 |
---|---|---|
committer | Steve Murphy <murf@digium.com> | 2008-06-16 20:43:46 +0000 |
commit | f4c85ebd229e87762b96a1713d9b6ac11d4b2ab1 (patch) | |
tree | 5a167c96702022ee82db6e25d50ebef659661b6f /main/pbx.c | |
parent | 39606a9c642df775cb6869de3b1b701311e0ad5a (diff) |
(closes issue #12689)
Reported by: ys
Many thanks to ys for doing the research on this problem.
I didn't think it would be best to unlock the contexts
and then relock them after the remove_extension2() call,
so I added an extra arg to remove_extension2() and set it
appropriately in each call. There were not that many.
I considered forcing the code to lock the contexts before
the call to remove_extension2(), but that would require
a slightly greater degree of changes, especially since
the find_context_locked is local to pbx.c
I did a simple sanity test to make sure the code doesn't
mess things up in general.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@123165 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/pbx.c')
-rw-r--r-- | main/pbx.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/main/pbx.c b/main/pbx.c index 6bb8a14f6..9654bd88f 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -4022,7 +4022,7 @@ int ast_context_remove_extension(const char *context, const char *extension, int struct ast_context *c = find_context_locked(context); if (c) { /* ... remove extension ... */ - ret = ast_context_remove_extension2(c, extension, priority, registrar); + ret = ast_context_remove_extension2(c, extension, priority, registrar, 1); ast_unlock_contexts(); } return ret; @@ -4038,14 +4038,15 @@ int ast_context_remove_extension(const char *context, const char *extension, int * it. * */ -int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar) +int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked) { struct ast_exten *exten, *prev_exten = NULL; struct ast_exten *peer; struct ast_exten ex, *exten2, *exten3; char dummy_name[1024]; - ast_wrlock_context(con); + if (!already_locked) + ast_wrlock_context(con); /* Handle this is in the new world */ @@ -4132,7 +4133,8 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension } if (!exten) { /* we can't find right extension */ - ast_unlock_context(con); + if (!already_locked) + ast_unlock_context(con); return -1; } @@ -4159,7 +4161,8 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension break; /* found our priority */ } if (!peer) { /* not found */ - ast_unlock_context(con); + if (!already_locked) + ast_unlock_context(con); return -1; } /* we are first priority extension? */ @@ -4192,7 +4195,8 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension destroy_exten(peer); /* XXX should we return -1 ? */ } - ast_unlock_context(con); + if (!already_locked) + ast_unlock_context(con); return 0; } @@ -7177,7 +7181,7 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context ast_verb(3, "Remove %s/%s/%d, registrar=%s; con=%s(%p); con->root=%p\n", tmp->name, prio_item->exten, prio_item->priority, registrar, con? con->name : "<nil>", con, con? con->root_table: NULL); - ast_context_remove_extension2(tmp, prio_item->exten, prio_item->priority, registrar); + ast_context_remove_extension2(tmp, prio_item->exten, prio_item->priority, registrar, 1); } ast_hashtab_end_traversal(prio_iter); } |