Make ast_channel_walk become ast_channel_walk_locked
authorMark Spencer <markster@digium.com>
Thu, 20 May 2004 16:30:10 +0000 (16:30 +0000)
committerMark Spencer <markster@digium.com>
Thu, 20 May 2004 16:30:10 +0000 (16:30 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3029 65c4cc65-6c06-0410-ace0-fbb531ad65f3

13 files changed:
apps/app_agi.c
apps/app_groupcount.c
apps/app_setcdruserfield.c
apps/app_softhangup.c
apps/app_zapscan.c
channel.c
channels/chan_mgcp.c
cli.c
include/asterisk/channel.h
manager.c
pbx.c
res/res_monitor.c
res/res_parking.c

index ba479b2..d7af708 100755 (executable)
@@ -692,15 +692,17 @@ static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, char **ar
            return RESULT_SUCCESS;
         } else if (argc==2) {
             /* one argument: look for info on the specified channel */
-            c = ast_channel_walk(NULL);
+            c = ast_channel_walk_locked(NULL);
             while (c) {
                 if (strcasecmp(argv[1],c->name)==0) {
                     /* we have a matching channel */
-                   ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
-                   fdprintf(agi->fd, "200 result=1\n");
+                           ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
+                           fdprintf(agi->fd, "200 result=1\n");
+                                       ast_mutex_unlock(&c->lock);
                     return RESULT_SUCCESS;
                 }
-                c = ast_channel_walk(c);
+                               ast_mutex_unlock(&c->lock);
+                c = ast_channel_walk_locked(c);
             }
             /* if we get this far no channel name matched the argument given */
             fdprintf(agi->fd, "200 result=-1\n");
@@ -753,13 +755,15 @@ static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, ch
            return RESULT_SUCCESS;
         } else if (argc==3) {
             /* one argument: look for info on the specified channel */
-            c = ast_channel_walk(NULL);
+            c = ast_channel_walk_locked(NULL);
             while (c) {
                 if (strcasecmp(argv[2],c->name)==0) {
                     fdprintf(agi->fd, "200 result=%d\n", c->_state);
+                                       ast_mutex_unlock(&c->lock);
                     return RESULT_SUCCESS;
                 }
-                c = ast_channel_walk(c);
+                               ast_mutex_unlock(&c->lock);
+                c = ast_channel_walk_locked(c);
             }
             /* if we get this far no channel name matched the argument given */
             fdprintf(agi->fd, "200 result=-1\n");
index ef7b92c..b97a774 100755 (executable)
@@ -58,20 +58,17 @@ LOCAL_USER_DECL;
 
 static int group_get_count(char *group)
 {
-       /* XXX ast_channel_walk needs to be modified to
-              prevent a race in which after we return the channel
-                  is no longer valid (or ast_channel_free can be modified
-                  just as well) XXX */
        struct ast_channel *chan;
        int count = 0;
        char *test;
        if (group && !ast_strlen_zero(group)) {
-               chan = ast_channel_walk(NULL);
+               chan = ast_channel_walk_locked(NULL);
                while(chan) {
                        test = pbx_builtin_getvar_helper(chan, "GROUP");
                        if (test && !strcasecmp(test, group))
                                count++;
-                       chan = ast_channel_walk(chan);
+                       ast_mutex_unlock(&chan->lock);
+                       chan = ast_channel_walk_locked(chan);
                }
        }
        return count;
index bb1bb33..d0ebd2e 100755 (executable)
@@ -76,11 +76,12 @@ static int action_setcdruserfield(struct mansession *s, struct message *m)
                astman_send_error(s, m, "No UserField specified");
                return 0;
        }
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while (c) {
                if (!strcasecmp(c->name, channel))
                        break;
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) {
                astman_send_error(s, m, "No such channel");
@@ -90,6 +91,7 @@ static int action_setcdruserfield(struct mansession *s, struct message *m)
                ast_cdr_appenduserfield(c, userfield);
        else
                ast_cdr_setuserfield(c, userfield);
+       ast_mutex_unlock(&c->lock);
        astman_send_ack(s, m, "CDR Userfield Set");
        return 0;
 }
index 497f038..43a4224 100755 (executable)
@@ -47,13 +47,15 @@ static int softhangup_exec(struct ast_channel *chan, void *data)
                return 0;
        }
        LOCAL_USER_ADD(u);
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while (c) {
                if (!strcasecmp(c->name, data)) {
                        ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
+                       ast_mutex_unlock(&c->lock);
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        LOCAL_USER_REMOVE(u);
 
index ab87f59..58a456f 100755 (executable)
@@ -54,17 +54,18 @@ LOCAL_USER_DECL;
 
 #define CONF_SIZE 160
 
-static struct ast_channel *get_zap_channel(int num) {
+static struct ast_channel *get_zap_channel_locked(int num) {
        struct ast_channel *c=NULL;
        char name[80];
 
        snprintf(name,sizeof(name),"Zap/%d-1",num);
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, name)) {
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (c)
                return c;
@@ -293,43 +294,44 @@ static int conf_exec(struct ast_channel *chan, void *data)
                 ast_answer(chan);
 
         for (;;) {
-               if (ast_waitfor(chan, 100) < 0)
-                       break;
-               f = ast_read(chan);
-               if (!f)
-                       break;
-               if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
+                       if (ast_waitfor(chan, 100) < 0)
+                               break;
+                       
+                       f = ast_read(chan);
+                       if (!f)
+                               break;
+                       if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
+                               ast_frfree(f);
+                               break;
+                       }
                        ast_frfree(f);
-                       break;
-               }
-               ast_frfree(f);
-               ichan = NULL;
-               if(input) {
-                       ichan = get_zap_channel(input);
-                       input = 0;
-               }
-
-               tempchan = ichan ? ichan : ast_channel_walk(tempchan);
-               
-               
-               if ( !tempchan && !lastchan )
-                       break;
-               if ( tempchan && tempchan->type && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
-                       ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
-                       strcpy(confstr, tempchan->name);
-                       if ((tmp = strchr(confstr,'-'))) {
-                               *tmp = '\0';
+                       ichan = NULL;
+                       if(input) {
+                               ichan = get_zap_channel_locked(input);
+                               input = 0;
                        }
-                       confno = atoi(strchr(confstr,'/') + 1);
-                       ast_stopstream(chan);
-                       ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
-                       res = conf_run(chan, confno, confflags);
-                       if (res<0) break;
-                       input = res;
-               }
-               lastchan = tempchan;
+       
+                       tempchan = ichan ? ichan : ast_channel_walk_locked(tempchan);
+                       
+                       
+                       if ( !tempchan && !lastchan )
+                               break;
+                       if ( tempchan && tempchan->type && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
+                               ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
+                               strcpy(confstr, tempchan->name);
+                               ast_mutex_unlock(&tempchan->lock);
+                               if ((tmp = strchr(confstr,'-'))) {
+                                       *tmp = '\0';
+                               }
+                               confno = atoi(strchr(confstr,'/') + 1);
+                               ast_stopstream(chan);
+                               ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
+                               res = conf_run(chan, confno, confflags);
+                               if (res<0) break;
+                               input = res;
+                       }
+                       lastchan = tempchan;
         }
-
         LOCAL_USER_REMOVE(u);
         return res;
 }
index 8d23fca..896fa89 100755 (executable)
--- a/channel.c
+++ b/channel.c
@@ -444,12 +444,15 @@ void ast_channel_undefer_dtmf(struct ast_channel *chan)
                chan->deferdtmf = 0;
 }
 
-struct ast_channel *ast_channel_walk(struct ast_channel *prev)
+struct ast_channel *ast_channel_walk_locked(struct ast_channel *prev)
 {
+       /* Returns next channel (locked) */
        struct ast_channel *l, *ret=NULL;
        ast_mutex_lock(&chlock);
        l = channels;
        if (!prev) {
+               if (l)
+                       ast_mutex_lock(&l->lock);
                ast_mutex_unlock(&chlock);
                return l;
        }
@@ -458,6 +461,8 @@ struct ast_channel *ast_channel_walk(struct ast_channel *prev)
                        ret = l->next;
                l = l->next;
        }
+       if (ret)
+               ast_mutex_lock(&ret->lock);
        ast_mutex_unlock(&chlock);
        return ret;
        
@@ -527,6 +532,12 @@ void ast_channel_free(struct ast_channel *chan)
        }
        if (!cur)
                ast_log(LOG_WARNING, "Unable to find channel in list\n");
+       else {
+               /* Lock and unlock the channel just to be sure nobody
+                  has it locked still */
+               ast_mutex_lock(&cur->lock);
+               ast_mutex_unlock(&cur->lock);
+       }
        if (chan->pvt->pvt)
                ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
 
@@ -1798,15 +1809,16 @@ int ast_parse_device_state(char *device)
        char *cut;
        struct ast_channel *chan;
 
-       chan = ast_channel_walk(NULL);
+       chan = ast_channel_walk_locked(NULL);
        while (chan) {
                strncpy(name, chan->name, sizeof(name)-1);
+               ast_mutex_unlock(&chan->lock);
                cut = strchr(name,'-');
                if (cut)
                        *cut = 0;
                if (!strcmp(name, device))
                        return AST_DEVICE_INUSE;
-               chan = ast_channel_walk(chan);
+               chan = ast_channel_walk_locked(chan);
        }
        return AST_DEVICE_UNKNOWN;
 }
index 5b7d0cf..ea29918 100755 (executable)
@@ -1764,6 +1764,8 @@ static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb
 {
        memset(req, 0, sizeof(struct mgcp_request));
        oseq++;
+       if (oseq > 999999999)
+               oseq = 1;
        init_req(p, req, verb);
        return 0;
 }
diff --git a/cli.c b/cli.c
index a48ce4b..9a23cb6 100755 (executable)
--- a/cli.c
+++ b/cli.c
@@ -291,13 +291,14 @@ static int handle_chanlist(int fd, int argc, char *argv[])
        int numchans = 0;
        if (argc != 2)
                return RESULT_SHOWUSAGE;
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        ast_cli(fd, FORMAT_STRING2, "Channel", "Context", "Extension", "Pri", "State", "Appl.", "Data");
        while(c) {
                ast_cli(fd, FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
                c->appl ? c->appl : "(None)", c->data ? ( !ast_strlen_zero(c->data) ? c->data : "(Empty)" ): "(None)");
                numchans++;
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        ast_cli(fd, "%d active channel(s)\n", numchans);
        return RESULT_SUCCESS;
@@ -335,14 +336,16 @@ static int handle_softhangup(int fd, int argc, char *argv[])
        struct ast_channel *c=NULL;
        if (argc != 3)
                return RESULT_SHOWUSAGE;
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, argv[2])) {
                        ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name);
                        ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
+                       ast_mutex_unlock(&c->lock);
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) 
                ast_cli(fd, "%s is not a known channel\n", argv[2]);
@@ -438,17 +441,20 @@ static int handle_debugchan(int fd, int argc, char *argv[])
        struct ast_channel *c=NULL;
        if (argc != 3)
                return RESULT_SHOWUSAGE;
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, argv[2])) {
                        c->fin |= 0x80000000;
                        c->fout |= 0x80000000;
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
-       if (c)
+       if (c) {
                ast_cli(fd, "Debugging enabled on channel %s\n", c->name);
+               ast_mutex_unlock(&c->lock);
+       }
        else
                ast_cli(fd, "No such channel %s\n", argv[2]);
        return RESULT_SUCCESS;
@@ -459,18 +465,20 @@ static int handle_nodebugchan(int fd, int argc, char *argv[])
        struct ast_channel *c=NULL;
        if (argc != 4)
                return RESULT_SHOWUSAGE;
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, argv[3])) {
                        c->fin &= 0x7fffffff;
                        c->fout &= 0x7fffffff;
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
-       if (c)
+       if (c) {
                ast_cli(fd, "Debugging disabled on channel %s\n", c->name);
-       else
+               ast_mutex_unlock(&c->lock);
+       } else
                ast_cli(fd, "No such channel %s\n", argv[2]);
        return RESULT_SUCCESS;
 }
@@ -482,7 +490,7 @@ static int handle_showchan(int fd, int argc, char *argv[])
        struct ast_channel *c=NULL;
        if (argc != 3)
                return RESULT_SHOWUSAGE;
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, argv[2])) {
                        ast_cli(fd, 
@@ -519,10 +527,11 @@ static int handle_showchan(int fd, int argc, char *argv[])
        c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
        ( c-> data ? (!ast_strlen_zero(c->data) ? c->data : "(Empty)") : "(None)"),
        c->stack, (c->blocking ? c->blockproc : "(Not Blocking)"));
-       
+               ast_mutex_unlock(&c->lock);
                break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) 
                ast_cli(fd, "%s is not a known channel\n", argv[2]);
@@ -533,15 +542,22 @@ static char *complete_ch(char *line, char *word, int pos, int state)
 {
        struct ast_channel *c;
        int which=0;
-       c = ast_channel_walk(NULL);
+       char *ret;
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strncasecmp(word, c->name, strlen(word))) {
                        if (++which > state)
                                break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
-       return c ? strdup(c->name) : NULL;
+       if (c) {
+               ret = strdup(c->name);
+               ast_mutex_unlock(&c->lock);
+       } else
+               ret = NULL;
+       return ret;
 }
 
 static char *complete_fn(char *line, char *word, int pos, int state)
index e420a19..baae962 100755 (executable)
@@ -624,8 +624,9 @@ int ast_recvchar(struct ast_channel *chan, int timeout);
  * \param prev where you want to start in the channel list
  * Browse the channels currently in use 
  * Returns the next channel in the list, NULL on end.
+ * If it returns a channel, that channel *has been locked*!
  */
-struct ast_channel *ast_channel_walk(struct ast_channel *prev);
+struct ast_channel *ast_channel_walk_locked(struct ast_channel *prev);
 
 //! Waits for a digit
 /*! 
index ed94d80..53dcf6f 100755 (executable)
--- a/manager.c
+++ b/manager.c
@@ -376,18 +376,20 @@ static int action_hangup(struct mansession *s, struct message *m)
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, name)) {
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) {
                astman_send_error(s, m, "No such channel");
                return 0;
        }
        ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
+       ast_mutex_unlock(&c->lock);
        astman_send_ack(s, m, "Channel Hungup");
        return 0;
 }
@@ -399,7 +401,7 @@ static int action_status(struct mansession *s, struct message *m)
        struct ast_channel *c;
        char bridge[256];
        astman_send_ack(s, m, "Channel status will follow");
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
         if (id && strlen(id))
                 snprintf(idText,256,"ActionID: %s\r\n",id);
        while(c) {
@@ -436,7 +438,8 @@ static int action_status(struct mansession *s, struct message *m)
                        c->name, c->callerid ? c->callerid : "<unknown>", 
                        ast_state2str(c->_state), bridge, c->uniqueid, idText);
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        ast_cli(s->fd,
        "Event: StatusComplete\r\n"
@@ -688,18 +691,20 @@ static int action_timeout(struct mansession *s, struct message *m)
                astman_send_error(s, m, "No timeout specified");
                return 0;
        }
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, name)) {
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) {
                astman_send_error(s, m, "No such channel");
                return 0;
        }
        ast_channel_setwhentohangup(c, timeout);
+       ast_mutex_unlock(&c->lock);
        astman_send_ack(s, m, "Timeout Set");
        return 0;
 }
diff --git a/pbx.c b/pbx.c
index ef5964f..11f2dea 100755 (executable)
--- a/pbx.c
+++ b/pbx.c
@@ -3592,15 +3592,21 @@ int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int pri
 int ast_async_goto_by_name(char *channame, char *context, char *exten, int priority)
 {
        struct ast_channel *chan;
-       chan = ast_channel_walk(NULL);
+       int res = -1;
+
+       chan = ast_channel_walk_locked(NULL);
        while(chan) {
                if (!strcasecmp(channame, chan->name))
                        break;
-               chan = ast_channel_walk(chan);
+               ast_mutex_unlock(&chan->lock);
+               chan = ast_channel_walk_locked(chan);
        }
-       if (chan)
-               return ast_async_goto(chan, context, exten, priority);
-       return -1;
+       
+       if (chan) {
+               res = ast_async_goto(chan, context, exten, priority);
+               ast_mutex_unlock(&chan->lock);
+       }
+       return res;
 }
 
 static void ext_strncpy(char *dst, char *src, int len)
index 22e365d..3d72170 100755 (executable)
@@ -333,12 +333,13 @@ static int start_monitor_action(struct mansession *s, struct message *m)
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, name)) {
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) {
                astman_send_error(s, m, "No such channel");
@@ -360,6 +361,7 @@ static int start_monitor_action(struct mansession *s, struct message *m)
                        return 0;
                }
        }
+       ast_mutex_unlock(&c->lock);
        astman_send_ack(s, m, "Started monitoring channel");
        return 0;
 }
@@ -368,22 +370,26 @@ static int stop_monitor_action(struct mansession *s, struct message *m)
 {
        struct ast_channel *c = NULL;
        char *name = astman_get_header(m, "Channel");
+       int res;
        if((!name)||(!strlen(name))) {
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, name)) {
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) {
                astman_send_error(s, m, "No such channel");
                return 0;
        }
-       if( ast_monitor_stop( c, 1 ) ) {
+       res = ast_monitor_stop( c, 1 );
+       ast_mutex_unlock(&c->lock);
+       if( res ) {
                astman_send_error(s, m, "Could not stop monitoring channel");
                return 0;
        }
@@ -404,12 +410,13 @@ static int change_monitor_action(struct mansession *s, struct message *m)
                astman_send_error(s, m, "No filename specified");
                return 0;
        }
-       c = ast_channel_walk(NULL);
+       c = ast_channel_walk_locked(NULL);
        while(c) {
                if (!strcasecmp(c->name, name)) {
                        break;
                }
-               c = ast_channel_walk(c);
+               ast_mutex_unlock(&c->lock);
+               c = ast_channel_walk_locked(c);
        }
        if (!c) {
                astman_send_error(s, m, "No such channel");
index 29b6368..e63f490 100755 (executable)
@@ -737,7 +737,7 @@ int ast_pickup_call(struct ast_channel *chan)
 {
        struct ast_channel *cur;
        int res = -1;
-       cur = ast_channel_walk(NULL);
+       cur = ast_channel_walk_locked(NULL);
        while(cur) {
                if (!cur->pbx && 
                        (cur != chan) &&
@@ -746,7 +746,8 @@ int ast_pickup_call(struct ast_channel *chan)
                         (cur->_state == AST_STATE_RING))) {
                                break;
                }
-               cur = ast_channel_walk(cur);
+               ast_mutex_unlock(&cur->lock);
+               cur = ast_channel_walk_locked(cur);
        }
        if (cur) {
                ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
@@ -759,6 +760,7 @@ int ast_pickup_call(struct ast_channel *chan)
                res = ast_channel_masquerade(cur, chan);
                if (res)
                        ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);           /* Done */
+               ast_mutex_unlock(&cur->lock);
        } else  {
                ast_log(LOG_DEBUG, "No call pickup possible...\n");
        }