mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Make ast_channel_walk become ast_channel_walk_locked
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3029 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -692,15 +692,17 @@ static int handle_hangup(struct ast_channel *chan, AGI *agi, int argc, char **ar
|
|||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
} else if (argc==2) {
|
} else if (argc==2) {
|
||||||
/* one argument: look for info on the specified channel */
|
/* one argument: look for info on the specified channel */
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while (c) {
|
while (c) {
|
||||||
if (strcasecmp(argv[1],c->name)==0) {
|
if (strcasecmp(argv[1],c->name)==0) {
|
||||||
/* we have a matching channel */
|
/* we have a matching channel */
|
||||||
ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
|
ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT);
|
||||||
fdprintf(agi->fd, "200 result=1\n");
|
fdprintf(agi->fd, "200 result=1\n");
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
return RESULT_SUCCESS;
|
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 */
|
/* if we get this far no channel name matched the argument given */
|
||||||
fdprintf(agi->fd, "200 result=-1\n");
|
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;
|
return RESULT_SUCCESS;
|
||||||
} else if (argc==3) {
|
} else if (argc==3) {
|
||||||
/* one argument: look for info on the specified channel */
|
/* one argument: look for info on the specified channel */
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while (c) {
|
while (c) {
|
||||||
if (strcasecmp(argv[2],c->name)==0) {
|
if (strcasecmp(argv[2],c->name)==0) {
|
||||||
fdprintf(agi->fd, "200 result=%d\n", c->_state);
|
fdprintf(agi->fd, "200 result=%d\n", c->_state);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
return RESULT_SUCCESS;
|
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 */
|
/* if we get this far no channel name matched the argument given */
|
||||||
fdprintf(agi->fd, "200 result=-1\n");
|
fdprintf(agi->fd, "200 result=-1\n");
|
||||||
|
@@ -58,20 +58,17 @@ LOCAL_USER_DECL;
|
|||||||
|
|
||||||
static int group_get_count(char *group)
|
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;
|
struct ast_channel *chan;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char *test;
|
char *test;
|
||||||
if (group && !ast_strlen_zero(group)) {
|
if (group && !ast_strlen_zero(group)) {
|
||||||
chan = ast_channel_walk(NULL);
|
chan = ast_channel_walk_locked(NULL);
|
||||||
while(chan) {
|
while(chan) {
|
||||||
test = pbx_builtin_getvar_helper(chan, "GROUP");
|
test = pbx_builtin_getvar_helper(chan, "GROUP");
|
||||||
if (test && !strcasecmp(test, group))
|
if (test && !strcasecmp(test, group))
|
||||||
count++;
|
count++;
|
||||||
chan = ast_channel_walk(chan);
|
ast_mutex_unlock(&chan->lock);
|
||||||
|
chan = ast_channel_walk_locked(chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
@@ -76,11 +76,12 @@ static int action_setcdruserfield(struct mansession *s, struct message *m)
|
|||||||
astman_send_error(s, m, "No UserField specified");
|
astman_send_error(s, m, "No UserField specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while (c) {
|
while (c) {
|
||||||
if (!strcasecmp(c->name, channel))
|
if (!strcasecmp(c->name, channel))
|
||||||
break;
|
break;
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c) {
|
||||||
astman_send_error(s, m, "No such channel");
|
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);
|
ast_cdr_appenduserfield(c, userfield);
|
||||||
else
|
else
|
||||||
ast_cdr_setuserfield(c, userfield);
|
ast_cdr_setuserfield(c, userfield);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
astman_send_ack(s, m, "CDR Userfield Set");
|
astman_send_ack(s, m, "CDR Userfield Set");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -47,13 +47,15 @@ static int softhangup_exec(struct ast_channel *chan, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LOCAL_USER_ADD(u);
|
LOCAL_USER_ADD(u);
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while (c) {
|
while (c) {
|
||||||
if (!strcasecmp(c->name, data)) {
|
if (!strcasecmp(c->name, data)) {
|
||||||
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
LOCAL_USER_REMOVE(u);
|
LOCAL_USER_REMOVE(u);
|
||||||
|
|
||||||
|
@@ -54,17 +54,18 @@ LOCAL_USER_DECL;
|
|||||||
|
|
||||||
#define CONF_SIZE 160
|
#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;
|
struct ast_channel *c=NULL;
|
||||||
char name[80];
|
char name[80];
|
||||||
|
|
||||||
snprintf(name,sizeof(name),"Zap/%d-1",num);
|
snprintf(name,sizeof(name),"Zap/%d-1",num);
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, name)) {
|
if (!strcasecmp(c->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (c)
|
if (c)
|
||||||
return c;
|
return c;
|
||||||
@@ -293,43 +294,44 @@ static int conf_exec(struct ast_channel *chan, void *data)
|
|||||||
ast_answer(chan);
|
ast_answer(chan);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (ast_waitfor(chan, 100) < 0)
|
if (ast_waitfor(chan, 100) < 0)
|
||||||
break;
|
break;
|
||||||
f = ast_read(chan);
|
|
||||||
if (!f)
|
f = ast_read(chan);
|
||||||
break;
|
if (!f)
|
||||||
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
|
break;
|
||||||
ast_frfree(f);
|
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
|
||||||
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';
|
|
||||||
}
|
}
|
||||||
confno = atoi(strchr(confstr,'/') + 1);
|
ast_frfree(f);
|
||||||
ast_stopstream(chan);
|
ichan = NULL;
|
||||||
ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
|
if(input) {
|
||||||
res = conf_run(chan, confno, confflags);
|
ichan = get_zap_channel_locked(input);
|
||||||
if (res<0) break;
|
input = 0;
|
||||||
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);
|
LOCAL_USER_REMOVE(u);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
18
channel.c
18
channel.c
@@ -444,12 +444,15 @@ void ast_channel_undefer_dtmf(struct ast_channel *chan)
|
|||||||
chan->deferdtmf = 0;
|
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;
|
struct ast_channel *l, *ret=NULL;
|
||||||
ast_mutex_lock(&chlock);
|
ast_mutex_lock(&chlock);
|
||||||
l = channels;
|
l = channels;
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
|
if (l)
|
||||||
|
ast_mutex_lock(&l->lock);
|
||||||
ast_mutex_unlock(&chlock);
|
ast_mutex_unlock(&chlock);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -458,6 +461,8 @@ struct ast_channel *ast_channel_walk(struct ast_channel *prev)
|
|||||||
ret = l->next;
|
ret = l->next;
|
||||||
l = l->next;
|
l = l->next;
|
||||||
}
|
}
|
||||||
|
if (ret)
|
||||||
|
ast_mutex_lock(&ret->lock);
|
||||||
ast_mutex_unlock(&chlock);
|
ast_mutex_unlock(&chlock);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -527,6 +532,12 @@ void ast_channel_free(struct ast_channel *chan)
|
|||||||
}
|
}
|
||||||
if (!cur)
|
if (!cur)
|
||||||
ast_log(LOG_WARNING, "Unable to find channel in list\n");
|
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)
|
if (chan->pvt->pvt)
|
||||||
ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
|
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;
|
char *cut;
|
||||||
struct ast_channel *chan;
|
struct ast_channel *chan;
|
||||||
|
|
||||||
chan = ast_channel_walk(NULL);
|
chan = ast_channel_walk_locked(NULL);
|
||||||
while (chan) {
|
while (chan) {
|
||||||
strncpy(name, chan->name, sizeof(name)-1);
|
strncpy(name, chan->name, sizeof(name)-1);
|
||||||
|
ast_mutex_unlock(&chan->lock);
|
||||||
cut = strchr(name,'-');
|
cut = strchr(name,'-');
|
||||||
if (cut)
|
if (cut)
|
||||||
*cut = 0;
|
*cut = 0;
|
||||||
if (!strcmp(name, device))
|
if (!strcmp(name, device))
|
||||||
return AST_DEVICE_INUSE;
|
return AST_DEVICE_INUSE;
|
||||||
chan = ast_channel_walk(chan);
|
chan = ast_channel_walk_locked(chan);
|
||||||
}
|
}
|
||||||
return AST_DEVICE_UNKNOWN;
|
return AST_DEVICE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@@ -1764,6 +1764,8 @@ static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb
|
|||||||
{
|
{
|
||||||
memset(req, 0, sizeof(struct mgcp_request));
|
memset(req, 0, sizeof(struct mgcp_request));
|
||||||
oseq++;
|
oseq++;
|
||||||
|
if (oseq > 999999999)
|
||||||
|
oseq = 1;
|
||||||
init_req(p, req, verb);
|
init_req(p, req, verb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
50
cli.c
50
cli.c
@@ -291,13 +291,14 @@ static int handle_chanlist(int fd, int argc, char *argv[])
|
|||||||
int numchans = 0;
|
int numchans = 0;
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
return RESULT_SHOWUSAGE;
|
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");
|
ast_cli(fd, FORMAT_STRING2, "Channel", "Context", "Extension", "Pri", "State", "Appl.", "Data");
|
||||||
while(c) {
|
while(c) {
|
||||||
ast_cli(fd, FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
|
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)");
|
c->appl ? c->appl : "(None)", c->data ? ( !ast_strlen_zero(c->data) ? c->data : "(Empty)" ): "(None)");
|
||||||
numchans++;
|
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);
|
ast_cli(fd, "%d active channel(s)\n", numchans);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
@@ -335,14 +336,16 @@ static int handle_softhangup(int fd, int argc, char *argv[])
|
|||||||
struct ast_channel *c=NULL;
|
struct ast_channel *c=NULL;
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, argv[2])) {
|
if (!strcasecmp(c->name, argv[2])) {
|
||||||
ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name);
|
ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name);
|
||||||
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c)
|
if (!c)
|
||||||
ast_cli(fd, "%s is not a known channel\n", argv[2]);
|
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;
|
struct ast_channel *c=NULL;
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, argv[2])) {
|
if (!strcasecmp(c->name, argv[2])) {
|
||||||
c->fin |= 0x80000000;
|
c->fin |= 0x80000000;
|
||||||
c->fout |= 0x80000000;
|
c->fout |= 0x80000000;
|
||||||
break;
|
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_cli(fd, "Debugging enabled on channel %s\n", c->name);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ast_cli(fd, "No such channel %s\n", argv[2]);
|
ast_cli(fd, "No such channel %s\n", argv[2]);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
@@ -459,18 +465,20 @@ static int handle_nodebugchan(int fd, int argc, char *argv[])
|
|||||||
struct ast_channel *c=NULL;
|
struct ast_channel *c=NULL;
|
||||||
if (argc != 4)
|
if (argc != 4)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, argv[3])) {
|
if (!strcasecmp(c->name, argv[3])) {
|
||||||
c->fin &= 0x7fffffff;
|
c->fin &= 0x7fffffff;
|
||||||
c->fout &= 0x7fffffff;
|
c->fout &= 0x7fffffff;
|
||||||
break;
|
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);
|
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]);
|
ast_cli(fd, "No such channel %s\n", argv[2]);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -482,7 +490,7 @@ static int handle_showchan(int fd, int argc, char *argv[])
|
|||||||
struct ast_channel *c=NULL;
|
struct ast_channel *c=NULL;
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, argv[2])) {
|
if (!strcasecmp(c->name, argv[2])) {
|
||||||
ast_cli(fd,
|
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->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-> data ? (!ast_strlen_zero(c->data) ? c->data : "(Empty)") : "(None)"),
|
||||||
c->stack, (c->blocking ? c->blockproc : "(Not Blocking)"));
|
c->stack, (c->blocking ? c->blockproc : "(Not Blocking)"));
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c)
|
if (!c)
|
||||||
ast_cli(fd, "%s is not a known channel\n", argv[2]);
|
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;
|
struct ast_channel *c;
|
||||||
int which=0;
|
int which=0;
|
||||||
c = ast_channel_walk(NULL);
|
char *ret;
|
||||||
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strncasecmp(word, c->name, strlen(word))) {
|
if (!strncasecmp(word, c->name, strlen(word))) {
|
||||||
if (++which > state)
|
if (++which > state)
|
||||||
break;
|
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)
|
static char *complete_fn(char *line, char *word, int pos, int state)
|
||||||
|
@@ -624,8 +624,9 @@ int ast_recvchar(struct ast_channel *chan, int timeout);
|
|||||||
* \param prev where you want to start in the channel list
|
* \param prev where you want to start in the channel list
|
||||||
* Browse the channels currently in use
|
* Browse the channels currently in use
|
||||||
* Returns the next channel in the list, NULL on end.
|
* 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
|
//! Waits for a digit
|
||||||
/*!
|
/*!
|
||||||
|
17
manager.c
17
manager.c
@@ -376,18 +376,20 @@ static int action_hangup(struct mansession *s, struct message *m)
|
|||||||
astman_send_error(s, m, "No channel specified");
|
astman_send_error(s, m, "No channel specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, name)) {
|
if (!strcasecmp(c->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c) {
|
||||||
astman_send_error(s, m, "No such channel");
|
astman_send_error(s, m, "No such channel");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
astman_send_ack(s, m, "Channel Hungup");
|
astman_send_ack(s, m, "Channel Hungup");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -399,7 +401,7 @@ static int action_status(struct mansession *s, struct message *m)
|
|||||||
struct ast_channel *c;
|
struct ast_channel *c;
|
||||||
char bridge[256];
|
char bridge[256];
|
||||||
astman_send_ack(s, m, "Channel status will follow");
|
astman_send_ack(s, m, "Channel status will follow");
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
if (id && strlen(id))
|
if (id && strlen(id))
|
||||||
snprintf(idText,256,"ActionID: %s\r\n",id);
|
snprintf(idText,256,"ActionID: %s\r\n",id);
|
||||||
while(c) {
|
while(c) {
|
||||||
@@ -436,7 +438,8 @@ static int action_status(struct mansession *s, struct message *m)
|
|||||||
c->name, c->callerid ? c->callerid : "<unknown>",
|
c->name, c->callerid ? c->callerid : "<unknown>",
|
||||||
ast_state2str(c->_state), bridge, c->uniqueid, idText);
|
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,
|
ast_cli(s->fd,
|
||||||
"Event: StatusComplete\r\n"
|
"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");
|
astman_send_error(s, m, "No timeout specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, name)) {
|
if (!strcasecmp(c->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c) {
|
||||||
astman_send_error(s, m, "No such channel");
|
astman_send_error(s, m, "No such channel");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ast_channel_setwhentohangup(c, timeout);
|
ast_channel_setwhentohangup(c, timeout);
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
astman_send_ack(s, m, "Timeout Set");
|
astman_send_ack(s, m, "Timeout Set");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
16
pbx.c
16
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)
|
int ast_async_goto_by_name(char *channame, char *context, char *exten, int priority)
|
||||||
{
|
{
|
||||||
struct ast_channel *chan;
|
struct ast_channel *chan;
|
||||||
chan = ast_channel_walk(NULL);
|
int res = -1;
|
||||||
|
|
||||||
|
chan = ast_channel_walk_locked(NULL);
|
||||||
while(chan) {
|
while(chan) {
|
||||||
if (!strcasecmp(channame, chan->name))
|
if (!strcasecmp(channame, chan->name))
|
||||||
break;
|
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);
|
if (chan) {
|
||||||
return -1;
|
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)
|
static void ext_strncpy(char *dst, char *src, int len)
|
||||||
|
@@ -333,12 +333,13 @@ static int start_monitor_action(struct mansession *s, struct message *m)
|
|||||||
astman_send_error(s, m, "No channel specified");
|
astman_send_error(s, m, "No channel specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, name)) {
|
if (!strcasecmp(c->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c) {
|
||||||
astman_send_error(s, m, "No such channel");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast_mutex_unlock(&c->lock);
|
||||||
astman_send_ack(s, m, "Started monitoring channel");
|
astman_send_ack(s, m, "Started monitoring channel");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -368,22 +370,26 @@ static int stop_monitor_action(struct mansession *s, struct message *m)
|
|||||||
{
|
{
|
||||||
struct ast_channel *c = NULL;
|
struct ast_channel *c = NULL;
|
||||||
char *name = astman_get_header(m, "Channel");
|
char *name = astman_get_header(m, "Channel");
|
||||||
|
int res;
|
||||||
if((!name)||(!strlen(name))) {
|
if((!name)||(!strlen(name))) {
|
||||||
astman_send_error(s, m, "No channel specified");
|
astman_send_error(s, m, "No channel specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, name)) {
|
if (!strcasecmp(c->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c) {
|
||||||
astman_send_error(s, m, "No such channel");
|
astman_send_error(s, m, "No such channel");
|
||||||
return 0;
|
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");
|
astman_send_error(s, m, "Could not stop monitoring channel");
|
||||||
return 0;
|
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");
|
astman_send_error(s, m, "No filename specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(NULL);
|
c = ast_channel_walk_locked(NULL);
|
||||||
while(c) {
|
while(c) {
|
||||||
if (!strcasecmp(c->name, name)) {
|
if (!strcasecmp(c->name, name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = ast_channel_walk(c);
|
ast_mutex_unlock(&c->lock);
|
||||||
|
c = ast_channel_walk_locked(c);
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c) {
|
||||||
astman_send_error(s, m, "No such channel");
|
astman_send_error(s, m, "No such channel");
|
||||||
|
@@ -737,7 +737,7 @@ int ast_pickup_call(struct ast_channel *chan)
|
|||||||
{
|
{
|
||||||
struct ast_channel *cur;
|
struct ast_channel *cur;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
cur = ast_channel_walk(NULL);
|
cur = ast_channel_walk_locked(NULL);
|
||||||
while(cur) {
|
while(cur) {
|
||||||
if (!cur->pbx &&
|
if (!cur->pbx &&
|
||||||
(cur != chan) &&
|
(cur != chan) &&
|
||||||
@@ -746,7 +746,8 @@ int ast_pickup_call(struct ast_channel *chan)
|
|||||||
(cur->_state == AST_STATE_RING))) {
|
(cur->_state == AST_STATE_RING))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cur = ast_channel_walk(cur);
|
ast_mutex_unlock(&cur->lock);
|
||||||
|
cur = ast_channel_walk_locked(cur);
|
||||||
}
|
}
|
||||||
if (cur) {
|
if (cur) {
|
||||||
ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
|
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);
|
res = ast_channel_masquerade(cur, chan);
|
||||||
if (res)
|
if (res)
|
||||||
ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name); /* Done */
|
ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name); /* Done */
|
||||||
|
ast_mutex_unlock(&cur->lock);
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_DEBUG, "No call pickup possible...\n");
|
ast_log(LOG_DEBUG, "No call pickup possible...\n");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user