diff options
author | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-06-11 14:29:58 +0000 |
---|---|---|
committer | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-06-11 14:29:58 +0000 |
commit | de3ad8cac3edf96a86ade3d678fbbac26a600d8f (patch) | |
tree | 6507c371ca1e390fd565e83b5fd1fc5917d6a4e1 /channel.c | |
parent | adcaa229ccbc58b7334cd600be41279e48d72f66 (diff) |
Improve deadlock handling of the channel list. (issue #8376 reported by one47)
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@68682 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channel.c')
-rw-r--r-- | channel.c | 24 |
1 files changed, 17 insertions, 7 deletions
@@ -771,19 +771,29 @@ static struct ast_channel *channel_find_locked(const struct ast_channel *prev, /* exit if chan not found or mutex acquired successfully */ done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0); /* this is slightly unsafe, as we _should_ hold the lock to access c->name */ - if (!done && c) + if (!done && c) { ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name); + if (retries == 9) { + /* We are about to fail due to a deadlock, so report this + * while we still have the list lock. + */ + ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n", msg, c, retries); + /* As we have deadlocked, we will skip this channel and see if + * there is another match. + * NOTE: No point doing this for a full-name match, as there + * can be no more matches. + */ + if (!(name && !namelen)) { + prev = c; + retries = -1; + } + } + } ast_mutex_unlock(&chlock); if (done) return c; usleep(1); } - /* - * c is surely not null, but we don't have the lock so cannot - * access c->name - */ - ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n", - msg, c, retries); return NULL; } |