aboutsummaryrefslogtreecommitdiffstats
path: root/main/channel.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2009-09-25 14:38:41 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2009-09-25 14:38:41 +0000
commit4a49a4a98b4dc40cc3ddda9bc656f44079474190 (patch)
treec1565bb5ec9ca2ddbd2a23bfe8bc6ee164106d7e /main/channel.c
parent5bec5836a0eca318b6211aaa7a36e20df1c3e978 (diff)
Don't use hash-based lookups for ast_channel_get_by_name_prefix().
ast_channel_get_full() tries to use OBJ_POINTER to optimize name-based channel lookups, but this will not work properly when the channel's full name was not supplied; for name-prefix searches, there is no value in doing a hash-based lookup, and in fact doing so could result in many channels being skipped. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@220494 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c81
1 files changed, 41 insertions, 40 deletions
diff --git a/main/channel.c b/main/channel.c
index f3e661d0e..d7c0fb4f7 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1367,6 +1367,45 @@ struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i)
return chan;
}
+static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct ast_channel *chan = obj, *cmp_args = arg;
+ size_t name_len;
+ int ret = CMP_MATCH;
+
+ /* This is sort of a hack. Basically, we're using an arbitrary field
+ * in ast_channel to pass the name_len for a prefix match. If this
+ * gets changed, then the uses of ao2_find() must be changed, too. */
+ name_len = cmp_args->rings;
+
+ ast_channel_lock(chan);
+
+ if (cmp_args->name) { /* match by name */
+ if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
+ (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
+ ret = 0; /* name match failed */
+ }
+ } else if (cmp_args->exten) {
+ if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
+ strcasecmp(chan->macrocontext, cmp_args->context)) {
+ ret = 0; /* context match failed */
+ }
+ if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
+ strcasecmp(chan->macroexten, cmp_args->exten)) {
+ ret = 0; /* exten match failed */
+ }
+ } else if (cmp_args->uniqueid) {
+ if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) ||
+ (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) {
+ ret = 0; /* uniqueid match failed */
+ }
+ }
+
+ ast_channel_unlock(chan);
+
+ return ret;
+}
+
static struct ast_channel *ast_channel_get_full(const char *name, size_t name_len,
const char *exten, const char *context)
{
@@ -1387,7 +1426,8 @@ static struct ast_channel *ast_channel_get_full(const char *name, size_t name_le
ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
}
- if ((chan = ao2_find(channels, &tmp_chan, !ast_strlen_zero(name) ? OBJ_POINTER : 0))) {
+ if ((chan = ao2_find(channels, &tmp_chan,
+ (!ast_strlen_zero(name) && (name_len != 0)) ? OBJ_POINTER : 0))) {
return chan;
}
@@ -6248,45 +6288,6 @@ static int ast_channel_hash_cb(const void *obj, const int flags)
return ast_str_case_hash(chan->name);
}
-static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
-{
- struct ast_channel *chan = obj, *cmp_args = arg;
- size_t name_len;
- int ret = CMP_MATCH;
-
- /* This is sort of a hack. Basically, we're using an arbitrary field
- * in ast_channel to pass the name_len for a prefix match. If this
- * gets changed, then the uses of ao2_find() must be changed, too. */
- name_len = cmp_args->rings;
-
- ast_channel_lock(chan);
-
- if (cmp_args->name) { /* match by name */
- if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
- (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
- ret = 0; /* name match failed */
- }
- } else if (cmp_args->exten) {
- if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
- strcasecmp(chan->macrocontext, cmp_args->context)) {
- ret = 0; /* context match failed */
- }
- if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
- strcasecmp(chan->macroexten, cmp_args->exten)) {
- ret = 0; /* exten match failed */
- }
- } else if (cmp_args->uniqueid) {
- if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) ||
- (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) {
- ret = 0; /* uniqueid match failed */
- }
- }
-
- ast_channel_unlock(chan);
-
- return ret;
-}
-
void ast_channels_init(void)
{
channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,