diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-08-06 03:55:49 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-08-06 03:55:49 +0000 |
commit | c29b0e1c060ae47289153cb63aeb6502d94f7e76 (patch) | |
tree | be48829beb2f7f8374454d7f998b9ecd4d4662fc /main/channel.c | |
parent | aab2719368a208aadf722bf508cdb16d29e5da64 (diff) |
Merged revisions 135949 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135949 | tilghman | 2008-08-05 22:53:36 -0500 (Tue, 05 Aug 2008) | 4 lines
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/trunk@135950 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/channel.c')
-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 276b3687c..431dd223e 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1117,24 +1117,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_RWLIST_RDLOCK(&channels); AST_RWLIST_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_RWLIST_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) && strcmp(c->uniqueid, name)) || |