Deadlock fixes
authorTilghman Lesher <tilghman@meg.abyt.es>
Wed, 12 Mar 2008 07:43:03 +0000 (07:43 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Wed, 12 Mar 2008 07:43:03 +0000 (07:43 +0000)
(closes issue #12143)
 Reported by: kactus
 Patches:
       20080312__bug12143__2.diff.txt uploaded by Corydon76 (license 14)
 Tested by: kactus

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

channels/chan_sip.c

index 9f3b830..e5ac3b2 100644 (file)
@@ -2250,6 +2250,7 @@ cleanup2:
 }
 
 #define sip_pvt_lock(x) ast_mutex_lock(&x->pvt_lock)
+#define sip_pvt_trylock(x) ast_mutex_trylock(&x->pvt_lock)
 #define sip_pvt_unlock(x) ast_mutex_unlock(&x->pvt_lock)
 
 /*!
@@ -5843,6 +5844,7 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
        }
 
        dialoglist_lock();
+restartsearch:
        for (p = dialoglist; p; p = p->next) {
                /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
                int found = FALSE;
@@ -5873,7 +5875,12 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
 
                if (found) {
                        /* Found the call */
-                       sip_pvt_lock(p);
+                       if (sip_pvt_trylock(p)) {
+                               dialoglist_unlock();
+                               usleep(1);
+                               dialoglist_lock();
+                               goto restartsearch;
+                       }
                        dialoglist_unlock();
                        return p;
                }
@@ -18332,7 +18339,13 @@ restartsearch:
                   get back to this point every millisecond or less)
                */
                for (dialog = dialoglist; dialog; dialog = dialog->next) {
-                       sip_pvt_lock(dialog);
+                       if (sip_pvt_trylock(dialog)) {
+                               dialoglist_unlock();
+                               usleep(1);
+                               dialoglist_lock();
+                               goto restartsearch;
+                       }
+
                        /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
                        check_rtp_timeout(dialog, t);
                        /* If we have sessions that needs to be destroyed, do it now */