Version 0.1.7 from FTP

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@259 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 24 years ago
parent 5d75c05877
commit a2828462c0

@ -175,6 +175,8 @@ static void *do_parking_thread(void *ignore)
pu = pu->next;
free(pt);
} else if (FD_ISSET(pu->chan->fd, &rfds) || FD_ISSET(pu->chan->fd, &efds)) {
if (FD_ISSET(pu->chan->fd, &efds))
pu->chan->exception = 1;
/* See if they need servicing */
f = ast_read(pu->chan);
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
@ -306,6 +308,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (o->stillgoing) {
o->chan->blocking = 0;
if (FD_ISSET(o->chan->fd, &rfds) || FD_ISSET(o->chan->fd, &efds)) {
if (FD_ISSET(o->chan->fd, &efds))
o->chan->exception = 1;
f = ast_read(o->chan);
if (f) {
if (f->frametype == AST_FRAME_CONTROL) {
@ -347,6 +351,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
}
if (FD_ISSET(in->fd, &rfds) || FD_ISSET(in->fd, &efds)) {
/* After unblocking the entirity of the list, check for the main channel */
if (FD_ISSET(in->fd, &efds))
in->exception = 1;
f = ast_read(in);
#if 0
if (f && (f->frametype != AST_FRAME_VOICE))
@ -370,8 +376,7 @@ static int bridge_call(struct ast_channel *chan, struct ast_channel *peer, int a
{
/* Copy voice back and forth between the two channels. Give the peer
the ability to transfer calls with '#<extension' syntax. */
struct ast_channel *cs[3];
int to = -1, len;
int len;
struct ast_frame *f;
struct ast_channel *who;
char newext[256], *ptr;
@ -382,98 +387,79 @@ static int bridge_call(struct ast_channel *chan, struct ast_channel *peer, int a
return -1;
peer->appl = "Bridged Call";
peer->data = chan->name;
cs[0] = chan;
cs[1] = peer;
for (/* ever */;;) {
who = ast_waitfor_n(cs, 2, &to);
if (!who) {
ast_log(LOG_WARNING, "Nobody there??\n");
continue;
}
f = ast_read(who);
if (!f || ((f->frametype == AST_FRAME_CONTROL) &&
((f->subclass == AST_CONTROL_HANGUP) ||
(f->subclass == AST_CONTROL_BUSY))))
for (;;) {
res = ast_channel_bridge(chan, peer, AST_BRIDGE_DTMF_CHANNEL_1, &f, &who);
if (res < 0) {
ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
return -1;
if ((f->frametype == AST_FRAME_VOICE) ||
(f->frametype == AST_FRAME_DTMF) ||
(f->frametype == AST_FRAME_TEXT)) {
if ((f->frametype == AST_FRAME_DTMF) && (who == peer) && allowredirect &&
(f->subclass == '#')) {
if (f->subclass == '#') {
memset(newext, 0, sizeof(newext));
ptr = newext;
len = ast_pbx_longest_extension(chan->context) + 1;
if (len < ast_pbx_longest_extension("default") + 1)
len = ast_pbx_longest_extension("default") + 1;
}
if (!f || ((f->frametype == AST_FRAME_CONTROL) && ((f->subclass == AST_CONTROL_HANGUP) || (f->subclass == AST_CONTROL_BUSY) ||
(f->subclass == AST_CONTROL_CONGESTION)))) {
res = -1;
break;
}
if ((f->frametype == AST_FRAME_DTMF) && (who == peer) && allowredirect &&
(f->subclass == '#')) {
memset(newext, 0, sizeof(newext));
ptr = newext;
len = ast_pbx_longest_extension(chan->context) + 1;
if (len < ast_pbx_longest_extension("default") + 1)
len = ast_pbx_longest_extension("default") + 1;
/* Transfer */
if ((res=ast_streamfile(peer, "pbx-transfer", chan->language)))
break;
if ((res=ast_waitstream(peer, AST_DIGIT_ANY)) < 0)
break;
ast_stopstream(peer);
if (res > 0) {
/* If they've typed a digit already, handle it */
newext[0] = res;
ptr++;
len --;
}
res = ast_readstring(peer, ptr, len, 3000, 2000, "#");
if (res)
break;
if (!strcmp(newext, parking_ext)) {
if (!park_call(chan, peer)) {
/* We return non-zero, but tell the PBX not to hang the channel when
the thread dies -- We have to be careful now though. We are responsible for
hanging up the channel, else it will never be hung up! */
res=AST_PBX_KEEPALIVE;
break;
} else {
ast_log(LOG_WARNING, "Unable to park call %s\n", chan->name);
}
/* XXX Maybe we should have another message here instead of invalid extension XXX */
} else if (ast_exists_extension(chan, peer->context, newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, peer->context, sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
res=0;
break;
} else if (ast_exists_extension(chan, "default", newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, "default", sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
res=0;
if ((res=ast_streamfile(peer, "pbx-transfer", chan->language)))
break;
if ((res=ast_waitstream(peer, AST_DIGIT_ANY)) < 0)
break;
ast_stopstream(peer);
if (res > 0) {
/* If they've typed a digit already, handle it */
newext[0] = res;
ptr++;
len --;
}
res = ast_readstring(peer, ptr, len, 3000, 2000, "#");
if (res)
break;
if (!strcmp(newext, parking_ext)) {
if (!park_call(chan, peer)) {
/* We return non-zero, but tell the PBX not to hang the channel when
the thread dies -- We have to be careful now though. We are responsible for
hanging up the channel, else it will never be hung up! */
res=AST_PBX_KEEPALIVE;
break;
} else {
ast_log(LOG_WARNING, "Unable to park call %s\n", chan->name);
}
res = ast_streamfile(peer, "pbx-invalid", chan->language);
if (res)
break;
res = ast_waitstream(peer, AST_DIGIT_ANY);
ast_stopstream(peer);
res = 0;
/* XXX Maybe we should have another message here instead of invalid extension XXX */
} else if (ast_exists_extension(chan, peer->context, newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, peer->context, sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
res=0;
break;
} else if (ast_exists_extension(chan, "default", newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, "default", sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
res=0;
break;
}
res = ast_streamfile(peer, "pbx-invalid", chan->language);
if (res)
break;
res = ast_waitstream(peer, AST_DIGIT_ANY);
ast_stopstream(peer);
res = 0;
} else {
#if 0
ast_log(LOG_DEBUG, "Read from %s\n", who->name);
#if 1
ast_log(LOG_DEBUG, "Read from %s (%d,%d)\n", who->name, f->frametype, f->subclass);
#endif
if (who == chan)
ast_write(peer, f);
else
ast_write(chan, f);
}
ast_frfree(f);
} else
ast_frfree(f);
/* Swap who gets priority */
cs[2] = cs[0];
cs[0] = cs[1];
cs[1] = cs[2];
}
return res;
}
@ -482,7 +468,7 @@ static int park_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
struct ast_channel *peer=NULL, *nchan;
struct ast_channel *peer=NULL;
struct parkeduser *pu, *pl=NULL;
int park;
if (!data) {
@ -509,13 +495,9 @@ static int park_exec(struct ast_channel *chan, void *data)
free(pu);
}
if (peer) {
/* Build a translator if necessary */
if (peer->format & chan->format)
nchan = chan;
else
nchan = ast_translator_create(chan, peer->format, AST_DIRECTION_BOTH);
if (!nchan) {
ast_log(LOG_WARNING, "Had to drop call because there was no translator for %s to %s.\n", chan->name, peer->name);
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
ast_hangup(peer);
return -1;
}
@ -523,9 +505,7 @@ static int park_exec(struct ast_channel *chan, void *data)
were the person called. */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
res = bridge_call(peer, nchan, 1);
if (nchan != chan)
ast_translator_destroy(nchan);
res = bridge_call(peer, chan, 1);
/* Simulate the PBX hanging up */
if (res != AST_PBX_KEEPALIVE)
ast_hangup(peer);
@ -546,7 +526,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
struct localuser *u;
char *info, *peers, *timeout, *tech, *number, *rest, *cur;
struct localuser *outgoing=NULL, *tmp;
struct ast_channel *peer, *npeer;
struct ast_channel *peer;
int to;
int allowredir=0;
char numsubst[AST_MAX_EXTENSION];
@ -562,25 +542,42 @@ static int dial_exec(struct ast_channel *chan, void *data)
/* Parse our arguments XXX Check for failure XXX */
info = malloc(strlen((char *)data) + AST_MAX_EXTENSION);
if (!info) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION);
peers = strtok(info, "|");
if (!peers) {
peers = info;
if (peers) {
timeout = strchr(info, '|');
if (timeout) {
*timeout = '\0';
timeout++;
}
} else
timeout = NULL;
if (!peers || !strlen(peers)) {
ast_log(LOG_WARNING, "Dial argument takes format (technology1/number1&technology2/number2...|optional timeout)\n");
goto out;
}
timeout = strtok(NULL, "|");
rest = peers;
cur = peers;
do {
cur = strtok(rest, "&");
/* Remember where to start next time */
rest = strtok(NULL, "\128");
rest = strchr(cur, '&');
if (rest) {
*rest = 0;
rest++;
}
/* Get a technology/[device:]number pair */
tech = strtok(cur, "/");
number = strtok(NULL, "&");
tech = cur;
number = strchr(tech, '/');
if (!number) {
ast_log(LOG_WARNING, "Dial argument takes format (technology1/[device:]number1&technology2/[device:]number2...|optional timeout)\n");
goto out;
}
*number = '\0';
number++;
tmp = malloc(sizeof(struct localuser));
if (!tmp) {
ast_log(LOG_WARNING, "Out of memory\n");
@ -598,15 +595,18 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
}
/* Request the peer */
tmp->chan = ast_request(tech, chan->format, numsubst);
tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
if (!tmp->chan) {
/* If we can't, just go on to the next call */
ast_log(LOG_WARNING, "Unable to create channel of type '%s'\n", tech);
free(tmp);
cur = rest;
continue;
}
tmp->chan->appl = "AppDial";
tmp->chan->data = "(Outgoing Line)";
if (chan->callerid)
tmp->chan->callerid = strdup(chan->callerid);
/* Place the call, but don't wait on the answer */
res = ast_call(tmp->chan, numsubst, 0);
if (res) {
@ -627,7 +627,9 @@ static int dial_exec(struct ast_channel *chan, void *data)
tmp->stillgoing = -1;
tmp->next = outgoing;
outgoing = tmp;
} while(rest);
cur = rest;
} while(cur);
if (timeout)
to = atoi(timeout) * 1000;
else
@ -649,21 +651,15 @@ static int dial_exec(struct ast_channel *chan, void *data)
conversation. */
hanguptree(outgoing, peer);
outgoing = NULL;
/* Build a translator if necessary */
if (peer->format & chan->format)
npeer = peer;
else
npeer = ast_translator_create(peer, chan->format, AST_DIRECTION_BOTH);
if (!npeer) {
ast_log(LOG_WARNING, "Had to drop call because there was no translator for %s to %s.\n", chan->name, peer->name);
ast_hangup(peer);
res = -1;
} else {
res = bridge_call(chan, npeer, allowredir);
if (npeer != peer)
ast_translator_destroy(npeer);
/* Make sure channels are compatible */
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
ast_hangup(peer);
return -1;
}
res = bridge_call(chan, peer, allowredir);
ast_hangup(peer);
}
out:
hanguptree(outgoing, NULL);
@ -711,3 +707,8 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

248
pbx.c

@ -61,6 +61,11 @@ struct ast_exten {
struct ast_exten *next;
};
struct ast_include {
char name[AST_MAX_EXTENSION];
struct ast_include *next;
};
/* An extension context */
struct ast_context {
/* Name of the context */
@ -71,6 +76,8 @@ struct ast_context {
struct ast_exten *root;
/* Link them together */
struct ast_context *next;
/* Include other contexts */
struct ast_include *includes;
};
@ -158,6 +165,9 @@ static int pbx_exec(struct ast_channel *c, /* Channel */
}
/* Go no deeper than this through includes (not counting loops) */
#define AST_PBX_MAX_STACK 64
#define HELPER_EXISTS 0
#define HELPER_SPAWN 1
#define HELPER_EXEC 2
@ -185,7 +195,7 @@ static void pbx_destroy(struct ast_pbx *p)
free(p);
}
static int extension_match(char *pattern, char *data)
static inline int extension_match(char *pattern, char *data)
{
int match;
/* If they're the same return */
@ -271,13 +281,82 @@ struct ast_context *ast_context_find(char *name)
return tmp;
}
static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, int action)
#define STATUS_NO_CONTEXT 1
#define STATUS_NO_EXTENSION 2
#define STATUS_NO_PRIORITY 3
#define STATUS_SUCCESS 4
static struct ast_exten *pbx_find_extension(char *context, char *exten, int priority, int action, char *incstack[], int *stacklen, int *status)
{
int x;
struct ast_context *tmp;
struct ast_exten *e, *reale;
struct ast_exten *e, *eroot;
struct ast_include *i;
/* Initialize status if appropriate */
if (!*stacklen)
*status = STATUS_NO_CONTEXT;
/* Check for stack overflow */
if (*stacklen >= AST_PBX_MAX_STACK) {
ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
return NULL;
}
/* Check first to see if we've already been checked */
for (x=0;x<*stacklen;x++) {
if (!strcasecmp(incstack[x], context))
return NULL;
}
tmp = contexts;
while(tmp) {
/* Match context */
if (!strcasecmp(tmp->name, context)) {
if (*status < STATUS_NO_EXTENSION)
*status = STATUS_NO_EXTENSION;
eroot = tmp->root;
while(eroot) {
/* Match extension */
if (extension_match(eroot->exten, exten) ||
((action == HELPER_CANMATCH) && (extension_close(eroot->exten, exten)))) {
e = eroot;
if (*status < STATUS_NO_PRIORITY)
*status = STATUS_NO_PRIORITY;
while(e) {
/* Match priority */
if (e->priority == priority) {
*status = STATUS_SUCCESS;
return e;
}
e = e->peer;
}
}
eroot = eroot->next;
}
/* Setup the stack */
incstack[*stacklen] = tmp->name;
(*stacklen)++;
/* Now try any includes we have in this context */
i = tmp->includes;
while(i) {
if ((e = pbx_find_extension(i->name, exten, priority, action, incstack, stacklen, status)))
return e;
i = i->next;
}
}
tmp = tmp->next;
}
return NULL;
}
static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, int action)
{
struct ast_exten *e;
struct ast_app *app;
int newstack = 0;
int res;
int status = 0;
char *incstack[AST_PBX_MAX_STACK];
int stacklen = 0;
if (pthread_mutex_lock(&conlock)) {
ast_log(LOG_WARNING, "Unable to obtain lock\n");
if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH))
@ -285,6 +364,70 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
else
return -1;
}
e = pbx_find_extension(context, exten, priority, action, incstack, &stacklen, &status);
if (e) {
switch(action) {
case HELPER_CANMATCH:
pthread_mutex_unlock(&conlock);
return -1;
case HELPER_EXISTS:
pthread_mutex_unlock(&conlock);
return -1;
case HELPER_SPAWN:
newstack++;
/* Fall through */
case HELPER_EXEC:
app = pbx_findapp(e->app);
pthread_mutex_unlock(&conlock);
if (app) {
strncpy(c->context, context, sizeof(c->context));
strncpy(c->exten, exten, sizeof(c->exten));
c->priority = priority;
if (option_debug)
ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
else if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n",
app->name, c->name, (e->data ? (char *)e->data : NULL), (newstack ? "in new stack" : "in same stack"));
c->appl = app->name;
c->data = e->data;
res = pbx_exec(c, app->execute, e->data, newstack);
c->appl = NULL;
c->data = NULL;
pthread_mutex_unlock(&conlock);
return res;
} else {
ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
return -1;
}
default:
ast_log(LOG_WARNING, "Huh (%d)?\n", action);
return -1;
}
} else {
pthread_mutex_unlock(&conlock);
switch(status) {
case STATUS_NO_CONTEXT:
if (action != HELPER_EXISTS)
ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
break;
case STATUS_NO_EXTENSION:
if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH))
ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
break;
case STATUS_NO_PRIORITY:
if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH))
ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
break;
default:
ast_log(LOG_DEBUG, "Shouldn't happen!\n");
}
if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH))
return -1;
else
return 0;
}
#if 0
tmp = contexts;
while(tmp) {
if (!strcasecmp(tmp->name, context)) {
@ -370,9 +513,12 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
return -1;
} else
return 0;
#endif
}
int ast_pbx_longest_extension(char *context)
{
/* XXX Not include-aware XXX */
struct ast_context *tmp;
struct ast_exten *e;
int len = 0;
@ -418,24 +564,36 @@ int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int p
return pbx_extension_helper(c, context, exten, priority, HELPER_SPAWN);
}
static void *pbx_thread(void *data)
int ast_pbx_run(struct ast_channel *c)
{
/* Oh joyeous kernel, we're a new thread, with nothing to do but
answer this channel and get it going. The setjmp stuff is fairly
confusing, but necessary to get smooth transitions between
the execution of different applications (without the use of
additional threads) */
struct ast_channel *c = data;
int firstpass = 1;
char digit;
char exten[256];
int pos;
int waittime;
int res=0;
/* A little initial setup here */
if (c->pbx)
ast_log(LOG_WARNING, "%s already has PBX structure??\n");
c->pbx = malloc(sizeof(struct ast_pbx));
if (!c->pbx) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
memset(c->pbx, 0, sizeof(struct ast_pbx));
/* Set reasonable defaults */
c->pbx->rtimeout = 10;
c->pbx->dtimeout = 5;
if (option_debug)
ast_log(LOG_DEBUG, "PBX_THREAD(%s)\n", c->name);
else if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s'\n", c->name);
else if (option_verbose > 1) {
if (c->callerid)
ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s' (%s)\n", c->name, c->callerid);
else
ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s'\n", c->name);
}
/* Start by trying whatever the channel is set to */
@ -467,7 +625,7 @@ static void *pbx_thread(void *data)
goto out;
}
/* If we're playing something in the background, wait for it to finish or for a digit */
if (c->stream || (c->trans && c->trans->stream)) {
if (c->stream) {
digit = ast_waitstream(c, AST_DIGIT_ANY);
ast_stopstream(c);
/* Hang up if something goes wrong */
@ -541,8 +699,20 @@ out:
c->pbx = NULL;
if (res != AST_PBX_KEEPALIVE)
ast_hangup(c);
return 0;
}
static void *pbx_thread(void *data)
{
/* Oh joyeous kernel, we're a new thread, with nothing to do but
answer this channel and get it going. The setjmp stuff is fairly
confusing, but necessary to get smooth transitions between
the execution of different applications (without the use of
additional threads) */
struct ast_channel *c = data;
ast_pbx_run(c);
pthread_exit(NULL);
return NULL;
}
int ast_pbx_start(struct ast_channel *c)
@ -552,17 +722,6 @@ int ast_pbx_start(struct ast_channel *c)
ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
return -1;
}
if (c->pbx)
ast_log(LOG_WARNING, "%s already has PBX structure??\n");
c->pbx = malloc(sizeof(struct ast_pbx));
if (!c->pbx) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
memset(c->pbx, 0, sizeof(struct ast_pbx));
/* Set reasonable defaults */
c->pbx->rtimeout = 10;
c->pbx->dtimeout = 5;
/* Start a new thread, and get something handling this channel. */
if (pthread_create(&t, NULL, pbx_thread, c)) {
ast_log(LOG_WARNING, "Failed to create new channel thread\n");
@ -655,6 +814,7 @@ struct ast_context *ast_context_create(char *name)
strncpy(tmp->name, name, sizeof(tmp->name));
tmp->root = NULL;
tmp->next = contexts;
tmp->includes = NULL;
contexts = tmp;
if (option_debug)
ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
@ -667,6 +827,36 @@ struct ast_context *ast_context_create(char *name)
return tmp;
}
int ast_context_add_include2(struct ast_context *con, char *value)
{
struct ast_include *inc, *incc, *incl = NULL;
inc = malloc(sizeof(struct ast_include));
if (!inc) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
strncpy(inc->name, value, sizeof(inc->name));
inc->next = NULL;
pthread_mutex_lock(&con->lock);
incc = con->includes;
while(incc) {
incl = incc;
if (!strcasecmp(incc->name, value)) {
/* Already there */
pthread_mutex_unlock(&con->lock);
return 0;
}
incc = incc->next;
}
if (incl)
incl->next = inc;
else
con->includes = inc;
pthread_mutex_unlock(&con->lock);
return 0;
}
int ast_add_extension2(struct ast_context *con,
int replace, char *extension, int priority,
char *application, void *data, void (*datad)(void *))
@ -815,6 +1005,7 @@ int ast_add_extension2(struct ast_context *con,
void ast_context_destroy(struct ast_context *con)
{
struct ast_context *tmp, *tmpl=NULL;
struct ast_include *tmpi, *tmpil= NULL;
pthread_mutex_lock(&conlock);
tmp = contexts;
while(tmp) {
@ -832,6 +1023,13 @@ void ast_context_destroy(struct ast_context *con)
/* Okay, now we're safe to let it go -- in a sense, we were
ready to let it go as soon as we locked it. */
pthread_mutex_unlock(&tmp->lock);
for (tmpi = tmp->includes; tmpi; ) {
/* Free includes */
tmpil = tmpi;
tmpi = tmpi->next;
free(tmpil);
tmpil = tmpi;
}
free(tmp);
pthread_mutex_unlock(&conlock);
return;

Loading…
Cancel
Save