diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-08-06 03:53:36 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-08-06 03:53:36 +0000 |
commit | 44ebcf17bcde54e7fa45f7528ccdabb3d389dd1d (patch) | |
tree | 5dad046cc261c257a4b0a9df57c1b78be2f01e29 | |
parent | 64cd17e1ddc1e1265c24417aca72957d7f70b4d8 (diff) |
Fix a longstanding bug in channel walking logic, and fix the explanation to
make sense.
(Closes issue #13124)
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@135949 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | main/channel.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/main/channel.c b/main/channel.c index ecf84ac21..3006e71cb 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1043,24 +1043,27 @@ static struct ast_channel *channel_find_locked(const struct ast_channel *prev, for (retries = 0; retries < 200; retries++) { int done; + /* Reset prev on each retry. See note below for the reason. */ + prev = _prev; AST_LIST_LOCK(&channels); AST_LIST_TRAVERSE(&channels, c, chan_list) { - prev = _prev; - if (prev) { /* look for next item */ + if (prev) { /* look for last item, first, before any evaluation */ if (c != prev) /* not this one */ continue; /* found, prepare to return c->next */ if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break; - /* If prev was the last item on the channel list, then we just - * want to return NULL, instead of trying to deref NULL in the - * next section. + /*!\note + * We're done searching through the list for the previous item. + * Any item after this point, we want to evaluate for a match. + * If we didn't set prev to NULL here, then we would only + * return matches for the first matching item (since the above + * "if (c != prev)" would not permit any other potential + * matches to reach the additional matching logic, below). + * Instead, it would just iterate until it once again found the + * original match, then iterate down to the end of the list and + * quit. */ prev = NULL; - /* We want prev to be NULL in case we end up doing more searching through - * the channel list to find the channel (ie: name searching). If we didn't - * set this to NULL the logic would just blow up - * XXX Need a better explanation for this ... - */ } if (name) { /* want match by name */ if ((!namelen && strcasecmp(c->name, name)) || |