]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 68682 via svnmerge from
authorJoshua Colp <jcolp@digium.com>
Mon, 11 Jun 2007 14:33:12 +0000 (14:33 +0000)
committerJoshua Colp <jcolp@digium.com>
Mon, 11 Jun 2007 14:33:12 +0000 (14:33 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r68682 | file | 2007-06-11 10:29:58 -0400 (Mon, 11 Jun 2007) | 2 lines

Improve deadlock handling of the channel list. (issue #8376 reported by one47)

........

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@68683 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/channel.c

index c1d3681d312b762131ce28ab9a46a16e016c8240..defc4b68763af0f650e70198c180729da56a680d 100644 (file)
@@ -1070,21 +1070,31 @@ static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
                /* exit if chan not found or mutex acquired successfully */
                /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
                done = c == NULL || ast_channel_trylock(c) == 0;
-               if (!done)
+               if (!done) {
                        if (option_debug)
                                ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
+                       if (retries == 9) {
+                               /* We are about to fail due to a deadlock, so report this
+                                * while we still have the list lock.
+                                */
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n", 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_LIST_UNLOCK(&channels);
                if (done)
                        return c;
                usleep(1);      /* give other threads a chance before retrying */
        }
-       /*
-        * c is surely not null, but we don't have the lock so cannot
-        * access c->name
-        */
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n",
-                       c, retries);
 
        return NULL;
 }