]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
It's another round of chan_iax2 fixes! Should hopefully fix the deadlock issues peopl...
authorJoshua Colp <jcolp@digium.com>
Wed, 1 Nov 2006 18:21:34 +0000 (18:21 +0000)
committerJoshua Colp <jcolp@digium.com>
Wed, 1 Nov 2006 18:21:34 +0000 (18:21 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@46775 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c

index e51ccafc7c6c9fb5c19c985aff098cfe2e0224fe..642dd6d618d94afda3412fc5003388d68e8432e8 100644 (file)
@@ -4957,18 +4957,10 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
                ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
                return -1;
        }
-       /* We release the lock for the call to prevent a deadlock, but it's okay because
-          only the current thread could possibly make it go away or make changes */
-       ast_mutex_unlock(&iaxsl[callno]);
+
        /* SLD: first call to lookup peer during registration */
        p = find_peer(peer, 1);
-       ast_mutex_lock(&iaxsl[callno]);
 
-       if (!iaxs[callno]) {
-               /* Call has disappeared */
-               ast_mutex_unlock(&iaxsl[callno]);
-               return -1;
-       }
        if (!p) {
                if (authdebug)
                        ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
@@ -5620,6 +5612,11 @@ static int update_registry(const char *name, struct sockaddr_in *sin, int callno
                /* Verify that the host is really there */
                iax2_poke_peer(p, callno);
        }               
+
+       /* Make sure our call still exists, an INVAL at the right point may make it go away */
+       if (!iaxs[callno])
+               return 0;
+
        /* Store socket fd */
        p->sockfd = fd;
        /* Setup the expiry */
@@ -8059,13 +8056,19 @@ static void *network_thread(void *ignore)
                        if (f->sentyet)
                                continue;
                        
+                       /* Try to lock the pvt, if we can't... don't fret - defer it till later */
+                       if (ast_mutex_trylock(&iaxsl[f->callno]))
+                               continue;
+
                        f->sentyet++;
-                       ast_mutex_lock(&iaxsl[f->callno]);
+
                        if (iaxs[f->callno]) {
                                send_packet(f);
                                count++;
                        } 
+
                        ast_mutex_unlock(&iaxsl[f->callno]);
+
                        if (f->retries < 0) {
                                /* This is not supposed to be retransmitted */
                                AST_LIST_REMOVE(&iaxq.queue, f, list);
@@ -8717,15 +8720,8 @@ static void prune_users(void)
 
 static void destroy_peer(struct iax2_peer *peer)
 {
-       int x;
        ast_free_ha(peer->ha);
-       for (x=0;x<IAX_MAX_CALLS;x++) {
-               ast_mutex_lock(&iaxsl[x]);
-               if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
-                       iax2_destroy(x);
-               }
-               ast_mutex_unlock(&iaxsl[x]);
-       }
+
        /* Delete it, it needs to disappear */
        if (peer->expire > -1)
                ast_sched_del(sched, peer->expire);
@@ -8733,10 +8729,14 @@ static void destroy_peer(struct iax2_peer *peer)
                ast_sched_del(sched, peer->pokeexpire);
        if (peer->callno > 0)
                iax2_destroy(peer->callno);
+
        register_peer_exten(peer, 0);
+
        if (peer->dnsmgr)
                ast_dnsmgr_release(peer->dnsmgr);
+
        ast_string_field_free_pools(peer);
+
        free(peer);
 }