Although I can't think of any scenario that it could result in a race, don't hold...
authorMark Spencer <markster@digium.com>
Wed, 9 Jun 2004 23:07:55 +0000 (23:07 +0000)
committerMark Spencer <markster@digium.com>
Wed, 9 Jun 2004 23:07:55 +0000 (23:07 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3184 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c
channels/chan_sip.c

index a89a0f5..8989bc6 100755 (executable)
@@ -2497,11 +2497,16 @@ static int iax2_getpeertrunk(struct sockaddr_in sin)
        return res;
 }
 
-static struct ast_channel *ast_iax2_new(struct chan_iax2_pvt *i, int state, int capability)
+static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
 {
        struct ast_channel *tmp;
+       struct chan_iax2_pvt *i;
+       /* Don't hold call lock */
+       ast_mutex_unlock(&iaxsl[callno]);
        tmp = ast_channel_alloc(1);
-       if (tmp) {
+       ast_mutex_lock(&iaxsl[callno]);
+       i = iaxs[callno];
+       if (i && tmp) {
                if (!ast_strlen_zero(i->username))
                        snprintf(tmp->name, sizeof(tmp->name), "IAX2[%s@%s]/%d", i->username, i->host, i->callno);
                else
@@ -5061,7 +5066,7 @@ retryowner:
                                                                if (option_verbose > 2) 
                                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepting unauthenticated call from %s, requested format = %d, actual format = %d\n", 
                                                                                inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat,format);
-                                                               if(!(c = ast_iax2_new(iaxs[fr.callno], AST_STATE_RING, format)))
+                                                               if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format)))
                                                                        iax2_destroy_nolock(fr.callno);
                                                        } else {
                                                                iaxs[fr.callno]->state |= IAX_STATE_TBD;
@@ -5332,7 +5337,7 @@ retryowner2:
                                                                ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s, requested format = %d, actual format = %d\n", 
                                                                        inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat,format);
                                                        iaxs[fr.callno]->state |= IAX_STATE_STARTED;
-                                                       if(!(c = ast_iax2_new(iaxs[fr.callno], AST_STATE_RING, format)))
+                                                       if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format)))
                                                                iax2_destroy_nolock(fr.callno);
                                                } else {
                                                        iaxs[fr.callno]->state |= IAX_STATE_TBD;
@@ -5359,7 +5364,7 @@ retryowner2:
                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat);
                                                iaxs[fr.callno]->state |= IAX_STATE_STARTED;
                                                send_command(iaxs[fr.callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
-                                               if(!(c = ast_iax2_new(iaxs[fr.callno], AST_STATE_RING, iaxs[fr.callno]->peerformat)))
+                                               if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, iaxs[fr.callno]->peerformat)))
                                                        iax2_destroy_nolock(fr.callno);
                                        }
                                }
@@ -5735,7 +5740,7 @@ static struct ast_channel *iax2_request(char *type, int format, void *data)
        iaxs[callno]->sendani = sendani;
        iaxs[callno]->maxtime = maxtime;
        iaxs[callno]->notransfer = notransfer;
-       c = ast_iax2_new(iaxs[callno], AST_STATE_DOWN, capability);
+       c = ast_iax2_new(callno, AST_STATE_DOWN, capability);
        ast_mutex_unlock(&iaxsl[callno]);
        if (c) {
                /* Choose a format we can live with */
index 74d84bd..c4de5be 100755 (executable)
@@ -1747,7 +1747,10 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
 {
        struct ast_channel *tmp;
        int fmt;
+       ast_mutex_unlock(&i->lock);
+       /* Don't hold a sip pvt lock while we allocate a channel */
        tmp = ast_channel_alloc(1);
+       ast_mutex_lock(&i->lock);
        if (tmp) {
                /* Select our native format based on codec preference until we receive
                   something from another device to the contrary. */
@@ -7183,7 +7186,9 @@ static struct ast_channel *sip_request(char *type, int format, void *data)
        printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
 #endif
        p->prefcodec = format;
+       ast_mutex_lock(&p->lock);
        tmpc = sip_new(p, AST_STATE_DOWN, host);
+       ast_mutex_unlock(&p->lock);
        if (!tmpc)
                sip_destroy(p);
        ast_update_use_count();