Clean up code and convert last two things (firmware/dialplan cache) to linked list macros.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43733 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Joshua Colp 19 years ago
parent ee13556e30
commit 481265e347

@ -228,7 +228,6 @@ static struct ast_flags globalflags = { 0 };
static pthread_t netthreadid = AST_PTHREADT_NULL;
static pthread_t schedthreadid = AST_PTHREADT_NULL;
AST_MUTEX_DEFINE_STATIC(sched_lock);
static int sched_halt = 0;
static ast_cond_t sched_cond;
enum {
@ -382,7 +381,7 @@ static struct iax2_trunk_peer {
AST_MUTEX_DEFINE_STATIC(tpeerlock);
struct iax_firmware {
struct iax_firmware *next;
AST_LIST_ENTRY(iax_firmware) list;
int fd;
int mmaplen;
int dead;
@ -608,7 +607,7 @@ struct chan_iax2_pvt {
int calling_tns;
int calling_pres;
int amaflags;
struct iax2_dpcache *dpentries;
AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
struct ast_variable *vars;
/*! last received remote rr */
struct iax_rr remote_rr;
@ -631,10 +630,7 @@ static AST_LIST_HEAD_STATIC(users, iax2_user);
static AST_LIST_HEAD_STATIC(peers, iax2_peer);
static struct ast_firmware_list {
struct iax_firmware *wares;
ast_mutex_t lock;
} waresl;
static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
/*! Extension exists */
#define CACHE_FLAG_EXISTS (1 << 0)
@ -653,7 +649,7 @@ static struct ast_firmware_list {
/*! Matchmore */
#define CACHE_FLAG_MATCHMORE (1 << 7)
static struct iax2_dpcache {
struct iax2_dpcache {
char peercontext[AST_MAX_CONTEXT];
char exten[AST_MAX_EXTENSION];
struct timeval orig;
@ -661,11 +657,11 @@ static struct iax2_dpcache {
int flags;
unsigned short callno;
int waiters[256];
struct iax2_dpcache *next;
struct iax2_dpcache *peer; /*!< For linking in peers */
} *dpcache;
AST_LIST_ENTRY(iax2_dpcache) cache_list;
AST_LIST_ENTRY(iax2_dpcache) peer_list;
};
AST_MUTEX_DEFINE_STATIC(dpcache_lock);
static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
static void reg_source_db(struct iax2_peer *p);
static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
@ -693,7 +689,6 @@ struct iax2_thread {
char curfunc[80];
#endif
int actions;
int halt;
pthread_t threadid;
int threadnum;
struct sockaddr_in iosin;
@ -1069,6 +1064,8 @@ static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, cons
jbconf.max_contig_interp = maxjitterinterps;
jb_setconf(tmp->jb,&jbconf);
AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
return tmp;
}
@ -1304,34 +1301,31 @@ static void destroy_firmware(struct iax_firmware *cur)
static int try_firmware(char *s)
{
struct stat stbuf;
struct iax_firmware *cur;
int ifd;
int fd;
int res;
struct iax_firmware *cur = NULL;
int ifd, fd, res, len, chunk;
struct ast_iax2_firmware_header *fwh, fwh2;
struct MD5Context md5;
unsigned char sum[16];
unsigned char buf[1024];
int len, chunk;
char *s2;
char *last;
s2 = alloca(strlen(s) + 100);
if (!s2) {
unsigned char sum[16], buf[1024];
char *s2, *last;
if (!(s2 = alloca(strlen(s) + 100))) {
ast_log(LOG_WARNING, "Alloca failed!\n");
return -1;
}
last = strrchr(s, '/');
if (last)
last++;
else
last = s;
snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
res = stat(s, &stbuf);
if (res < 0) {
if ((res = stat(s, &stbuf) < 0)) {
ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
return -1;
}
/* Make sure it's not a directory */
if (S_ISDIR(stbuf.st_mode))
return -1;
@ -1409,8 +1403,8 @@ static int try_firmware(char *s)
close(fd);
return -1;
}
cur = waresl.wares;
while(cur) {
AST_LIST_TRAVERSE(&firmwares, cur, list) {
if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
/* Found a candidate */
if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
@ -1422,20 +1416,16 @@ static int try_firmware(char *s)
close(fd);
return 0;
}
cur = cur->next;
}
if (!cur) {
/* Allocate a new one and link it */
if ((cur = ast_calloc(1, sizeof(*cur)))) {
cur->fd = -1;
cur->next = waresl.wares;
waresl.wares = cur;
}
if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
cur->fd = -1;
AST_LIST_INSERT_TAIL(&firmwares, cur, list);
}
if (cur) {
if (cur->fwh) {
if (cur->fwh)
munmap(cur->fwh, cur->mmaplen);
}
if (cur->fd > -1)
close(cur->fd);
cur->fwh = fwh;
@ -1443,25 +1433,27 @@ static int try_firmware(char *s)
cur->mmaplen = stbuf.st_size;
cur->dead = 0;
}
return 0;
}
static int iax_check_version(char *dev)
{
int res = 0;
struct iax_firmware *cur;
if (!ast_strlen_zero(dev)) {
ast_mutex_lock(&waresl.lock);
cur = waresl.wares;
while(cur) {
if (!strcmp(dev, (char *)cur->fwh->devname)) {
res = ntohs(cur->fwh->version);
break;
}
cur = cur->next;
struct iax_firmware *cur = NULL;
if (ast_strlen_zero(dev))
return 0;
AST_LIST_LOCK(&firmwares);
AST_LIST_TRAVERSE(&firmwares, cur, list) {
if (!strcmp(dev, (char *)cur->fwh->devname)) {
res = ntohs(cur->fwh->version);
break;
}
ast_mutex_unlock(&waresl.lock);
}
AST_LIST_UNLOCK(&firmwares);
return res;
}
@ -1472,51 +1464,52 @@ static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev
unsigned int start = (desc >> 8) & 0xffffff;
unsigned int bytes;
struct iax_firmware *cur;
if (!ast_strlen_zero((char *)dev) && bs) {
start *= bs;
ast_mutex_lock(&waresl.lock);
cur = waresl.wares;
while(cur) {
if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
if (start < ntohl(cur->fwh->datalen)) {
bytes = ntohl(cur->fwh->datalen) - start;
if (bytes > bs)
bytes = bs;
iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
} else {
bytes = 0;
iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
}
if (bytes == bs)
res = 0;
else
res = 1;
break;
}
cur = cur->next;
if (ast_strlen_zero((char *)dev) || !bs)
return -1;
start *= bs;
AST_LIST_LOCK(&firmwares);
AST_LIST_TRAVERSE(&firmwares, cur, list) {
if (strcmp((char *)dev, (char *)cur->fwh->devname))
continue;
iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
if (start < ntohl(cur->fwh->datalen)) {
bytes = ntohl(cur->fwh->datalen) - start;
if (bytes > bs)
bytes = bs;
iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
} else {
bytes = 0;
iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
}
ast_mutex_unlock(&waresl.lock);
if (bytes == bs)
res = 0;
else
res = 1;
break;
}
AST_LIST_UNLOCK(&firmwares);
return res;
}
static void reload_firmware(void)
{
struct iax_firmware *cur, *curl, *curp;
struct iax_firmware *cur = NULL;
DIR *fwd;
struct dirent *de;
char dir[256];
char fn[256];
char dir[256], fn[256];
AST_LIST_LOCK(&firmwares);
/* Mark all as dead */
ast_mutex_lock(&waresl.lock);
cur = waresl.wares;
while(cur) {
AST_LIST_TRAVERSE(&firmwares, cur, list)
cur->dead = 1;
cur = cur->next;
}
/* Now that we've freed them, load the new ones */
/* Now that we have marked them dead... load new ones */
snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
fwd = opendir(dir);
if (fwd) {
@ -1534,23 +1527,13 @@ static void reload_firmware(void)
ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
/* Clean up leftovers */
cur = waresl.wares;
curp = NULL;
while(cur) {
curl = cur;
cur = cur->next;
if (curl->dead) {
if (curp) {
curp->next = cur;
} else {
waresl.wares = cur;
}
destroy_firmware(curl);
} else {
curp = cur;
}
AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
if (!cur->dead)
continue;
AST_LIST_REMOVE_CURRENT(&firmwares, list);
destroy_firmware(cur);
}
ast_mutex_unlock(&waresl.lock);
AST_LIST_TRAVERSE_SAFE_END
}
static int __do_deliver(void *data)
@ -1687,20 +1670,22 @@ static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
static int iax2_predestroy(int callno)
{
struct ast_channel *c;
struct chan_iax2_pvt *pvt;
struct ast_channel *c = NULL;
struct chan_iax2_pvt *pvt = NULL;
ast_mutex_lock(&iaxsl[callno]);
pvt = iaxs[callno];
if (!pvt) {
if (!(pvt = iaxs[callno])) {
ast_mutex_unlock(&iaxsl[callno]);
return -1;
}
if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
iax2_destroy_helper(pvt);
ast_set_flag(pvt, IAX_ALREADYGONE);
}
c = pvt->owner;
if (c) {
if ((c = pvt->owner)) {
c->_softhangup |= AST_SOFTHANGUP_DEV;
c->tech_pvt = NULL;
ast_queue_hangup(c);
@ -1708,7 +1693,9 @@ static int iax2_predestroy(int callno)
ast_atomic_fetchadd_int(&usecnt, -1);
ast_update_use_count();
}
ast_mutex_unlock(&iaxsl[callno]);
return 0;
}
@ -1723,9 +1710,9 @@ static int iax2_predestroy_nolock(int callno)
static void iax2_destroy(int callno)
{
struct chan_iax2_pvt *pvt;
struct iax_frame *cur;
struct ast_channel *owner;
struct chan_iax2_pvt *pvt = NULL;
struct iax_frame *cur = NULL;
struct ast_channel *owner = NULL;
retry:
ast_mutex_lock(&iaxsl[callno]);
@ -2096,16 +2083,18 @@ static int iax2_show_stats(int fd, int argc, char *argv[])
static int iax2_show_cache(int fd, int argc, char *argv[])
{
struct iax2_dpcache *dp;
char tmp[1024], *pc;
int s;
int x,y;
struct iax2_dpcache *dp = NULL;
char tmp[1024], *pc = NULL;
int s, x, y;
struct timeval tv;
gettimeofday(&tv, NULL);
ast_mutex_lock(&dpcache_lock);
dp = dpcache;
AST_LIST_LOCK(&dpcache);
ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
while(dp) {
AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
s = dp->expiry.tv_sec - tv.tv_sec;
tmp[0] = '\0';
if (dp->flags & CACHE_FLAG_EXISTS)
@ -2142,9 +2131,10 @@ static int iax2_show_cache(int fd, int argc, char *argv[])
ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
else
ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
dp = dp->next;
}
ast_mutex_unlock(&dpcache_lock);
AST_LIST_LOCK(&dpcache);
return RESULT_SUCCESS;
}
@ -4198,18 +4188,21 @@ static int iax2_show_firmware(int fd, int argc, char *argv[])
#else /* __FreeBSD__ */
#define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */
#endif /* __FreeBSD__ */
struct iax_firmware *cur;
struct iax_firmware *cur = NULL;
if ((argc != 3) && (argc != 4))
return RESULT_SHOWUSAGE;
ast_mutex_lock(&waresl.lock);
AST_LIST_LOCK(&firmwares);
ast_cli(fd, FORMAT2, "Device", "Version", "Size");
for (cur = waresl.wares;cur;cur = cur->next) {
AST_LIST_TRAVERSE(&firmwares, cur, list)
if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
(int)ntohl(cur->fwh->datalen));
}
ast_mutex_unlock(&waresl.lock);
AST_LIST_UNLOCK(&firmwares);
return RESULT_SUCCESS;
#undef FORMAT
#undef FORMAT2
@ -5231,15 +5224,12 @@ static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
{
char exten[256] = "";
int status = CACHE_FLAG_UNKNOWN;
int expiry = iaxdefaultdpcache;
int x;
int matchmore = 0;
struct iax2_dpcache *dp, *prev;
int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
struct iax2_dpcache *dp = NULL;
if (ies->called_number)
ast_copy_string(exten, ies->called_number, sizeof(exten));
if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
status = CACHE_FLAG_EXISTS;
else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
@ -5247,40 +5237,31 @@ static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
status = CACHE_FLAG_NONEXISTENT;
if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
/* Don't really do anything with this */
}
if (ies->refresh)
expiry = ies->refresh;
if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
matchmore = CACHE_FLAG_MATCHMORE;
ast_mutex_lock(&dpcache_lock);
prev = NULL;
dp = pvt->dpentries;
while(dp) {
if (!strcmp(dp->exten, exten)) {
/* Let them go */
if (prev)
prev->peer = dp->peer;
else
pvt->dpentries = dp->peer;
dp->peer = NULL;
dp->callno = 0;
dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
if (dp->flags & CACHE_FLAG_PENDING) {
dp->flags &= ~CACHE_FLAG_PENDING;
dp->flags |= status;
dp->flags |= matchmore;
}
/* Wake up waiters */
for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
if (dp->waiters[x] > -1)
write(dp->waiters[x], "asdf", 4);
}
prev = dp;
dp = dp->peer;
AST_LIST_LOCK(&dpcache);
AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
if (strcmp(dp->exten, exten))
continue;
AST_LIST_REMOVE_CURRENT(&dpcache, peer_list);
dp->callno = 0;
dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
if (dp->flags & CACHE_FLAG_PENDING) {
dp->flags &= ~CACHE_FLAG_PENDING;
dp->flags |= status;
dp->flags |= matchmore;
}
/* Wake up waiters */
for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
if (dp->waiters[x] > -1)
write(dp->waiters[x], "asdf", 4);
}
ast_mutex_unlock(&dpcache_lock);
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_UNLOCK(&dpcache);
return 0;
}
@ -7024,15 +7005,11 @@ retryowner2:
}
}
}
ast_mutex_lock(&dpcache_lock);
dp = iaxs[fr->callno]->dpentries;
while(dp) {
if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
AST_LIST_LOCK(&dpcache);
AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
iax2_dprequest(dp, fr->callno);
}
dp = dp->peer;
}
ast_mutex_unlock(&dpcache_lock);
AST_LIST_UNLOCK(&dpcache);
break;
case IAX_COMMAND_POKE:
/* Send back a pong packet with the original timestamp */
@ -7607,11 +7584,6 @@ static void *iax2_process_thread(void *data)
}
ast_mutex_unlock(&thread->lock);
/* If we were signalled, then we are already out of both lists or we are shutting down */
if (thread->halt) {
break;
}
/* Add ourselves to the active list now */
AST_LIST_LOCK(&active_list);
AST_LIST_INSERT_HEAD(&active_list, thread, list);
@ -7655,11 +7627,6 @@ static void *iax2_process_thread(void *data)
}
}
/* Free our own memory */
ast_mutex_destroy(&thread->lock);
ast_cond_destroy(&thread->cond);
free(thread);
return NULL;
}
@ -8015,17 +7982,17 @@ static void *sched_thread(void *ignore)
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
pthread_testcancel();
ast_mutex_lock(&sched_lock);
ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
if (sched_halt == 1)
break;
ast_mutex_unlock(&sched_lock);
pthread_testcancel();
count = ast_sched_runq(sched);
if (count >= 20)
ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
}
ast_mutex_unlock(&sched_lock);
return NULL;
}
@ -9211,48 +9178,32 @@ static int cache_get_callno_locked(const char *data)
static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
{
struct iax2_dpcache *dp, *prev = NULL, *next;
struct iax2_dpcache *dp = NULL;
struct timeval tv;
int x;
int com[2];
int timeout;
int old=0;
int outfd;
int abort;
int callno;
struct ast_channel *c;
struct ast_frame *f;
int x, com[2], timeout, old = 0, outfd, abort, callno;
struct ast_channel *c = NULL;
struct ast_frame *f = NULL;
gettimeofday(&tv, NULL);
dp = dpcache;
while(dp) {
next = dp->next;
/* Expire old caches */
AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
if (ast_tvcmp(tv, dp->expiry) > 0) {
/* It's expired, let it disappear */
if (prev)
prev->next = dp->next;
else
dpcache = dp->next;
if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
/* Free memory and go again */
free(dp);
} else {
ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
}
dp = next;
continue;
AST_LIST_REMOVE_CURRENT(&dpcache, cache_list);
if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
else
free(dp);
continue;
}
/* We found an entry that matches us! */
if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
break;
prev = dp;
dp = next;
}
AST_LIST_TRAVERSE_SAFE_END
if (!dp) {
/* No matching entry. Create a new one. */
/* First, can we make a callno? */
callno = cache_get_callno_locked(data);
if (callno < 0) {
if ((callno = cache_get_callno_locked(data)) < 0) {
ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
return NULL;
}
@ -9266,18 +9217,18 @@ static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *dat
dp->orig = dp->expiry;
/* Expires in 30 mins by default */
dp->expiry.tv_sec += iaxdefaultdpcache;
dp->next = dpcache;
dp->flags = CACHE_FLAG_PENDING;
for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
dp->waiters[x] = -1;
dpcache = dp;
dp->peer = iaxs[callno]->dpentries;
iaxs[callno]->dpentries = dp;
/* Insert into the lists */
AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
/* Send the request if we're already up */
if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
iax2_dprequest(dp, callno);
ast_mutex_unlock(&iaxsl[callno]);
}
/* By here we must have a dp */
if (dp->flags & CACHE_FLAG_PENDING) {
/* Okay, here it starts to get nasty. We need a pipe now to wait
@ -9299,31 +9250,27 @@ static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *dat
/* Okay, now we wait */
timeout = iaxdefaulttimeout * 1000;
/* Temporarily unlock */
ast_mutex_unlock(&dpcache_lock);
AST_LIST_UNLOCK(&dpcache);
/* Defer any dtmf */
if (chan)
old = ast_channel_defer_dtmf(chan);
abort = 0;
while(timeout) {
c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
if (outfd > -1) {
if (outfd > -1)
break;
if (!c)
continue;
if (!(f = ast_read(c))) {
abort = 1;
break;
}
if (c) {
f = ast_read(c);
if (f)
ast_frfree(f);
else {
/* Got hung up on, abort! */
break;
abort = 1;
}
}
ast_frfree(f);
}
if (!timeout) {
ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
}
ast_mutex_lock(&dpcache_lock);
AST_LIST_LOCK(&dpcache);
dp->waiters[x] = -1;
close(com[1]);
close(com[0]);
@ -9359,23 +9306,23 @@ static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *dat
/*! \brief Part of the IAX2 switch interface */
static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
{
struct iax2_dpcache *dp;
int res = 0;
struct iax2_dpcache *dp = NULL;
#if 0
ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
#endif
if ((priority != 1) && (priority != 2))
return 0;
ast_mutex_lock(&dpcache_lock);
dp = find_cache(chan, data, context, exten, priority);
if (dp) {
AST_LIST_LOCK(&dpcache);
if ((dp = find_cache(chan, data, context, exten, priority))) {
if (dp->flags & CACHE_FLAG_EXISTS)
res= 1;
}
ast_mutex_unlock(&dpcache_lock);
if (!dp) {
res = 1;
} else {
ast_log(LOG_WARNING, "Unable to make DP cache\n");
}
AST_LIST_UNLOCK(&dpcache);
return res;
}
@ -9383,22 +9330,22 @@ static int iax2_exists(struct ast_channel *chan, const char *context, const char
static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
{
int res = 0;
struct iax2_dpcache *dp;
struct iax2_dpcache *dp = NULL;
#if 0
ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
#endif
if ((priority != 1) && (priority != 2))
return 0;
ast_mutex_lock(&dpcache_lock);
dp = find_cache(chan, data, context, exten, priority);
if (dp) {
AST_LIST_LOCK(&dpcache);
if ((dp = find_cache(chan, data, context, exten, priority))) {
if (dp->flags & CACHE_FLAG_CANEXIST)
res= 1;
}
ast_mutex_unlock(&dpcache_lock);
if (!dp) {
res = 1;
} else {
ast_log(LOG_WARNING, "Unable to make DP cache\n");
}
AST_LIST_UNLOCK(&dpcache);
return res;
}
@ -9406,22 +9353,22 @@ static int iax2_canmatch(struct ast_channel *chan, const char *context, const ch
static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
{
int res = 0;
struct iax2_dpcache *dp;
struct iax2_dpcache *dp = NULL;
#if 0
ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
#endif
if ((priority != 1) && (priority != 2))
return 0;
ast_mutex_lock(&dpcache_lock);
dp = find_cache(chan, data, context, exten, priority);
if (dp) {
AST_LIST_LOCK(&dpcache);
if ((dp = find_cache(chan, data, context, exten, priority))) {
if (dp->flags & CACHE_FLAG_MATCHMORE)
res= 1;
}
ast_mutex_unlock(&dpcache_lock);
if (!dp) {
res = 1;
} else {
ast_log(LOG_WARNING, "Unable to make DP cache\n");
}
AST_LIST_UNLOCK(&dpcache);
return res;
}
@ -9431,8 +9378,8 @@ static int iax2_exec(struct ast_channel *chan, const char *context, const char *
char odata[256];
char req[256];
char *ncontext;
struct iax2_dpcache *dp;
struct ast_app *dial;
struct iax2_dpcache *dp = NULL;
struct ast_app *dial = NULL;
#if 0
ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack);
#endif
@ -9447,9 +9394,9 @@ static int iax2_exec(struct ast_channel *chan, const char *context, const char *
return -1;
} else if (priority != 1)
return -1;
ast_mutex_lock(&dpcache_lock);
dp = find_cache(chan, data, context, exten, priority);
if (dp) {
AST_LIST_LOCK(&dpcache);
if ((dp = find_cache(chan, data, context, exten, priority))) {
if (dp->flags & CACHE_FLAG_EXISTS) {
ast_copy_string(odata, data, sizeof(odata));
ncontext = strchr(odata, '/');
@ -9463,18 +9410,18 @@ static int iax2_exec(struct ast_channel *chan, const char *context, const char *
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
} else {
ast_mutex_unlock(&dpcache_lock);
AST_LIST_UNLOCK(&dpcache);
ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
return -1;
}
}
ast_mutex_unlock(&dpcache_lock);
dial = pbx_findapp("Dial");
if (dial) {
AST_LIST_UNLOCK(&dpcache);
if ((dial = pbx_findapp("Dial")))
return pbx_exec(chan, dial, req);
} else {
else
ast_log(LOG_WARNING, "No dial application registered\n");
}
return -1;
}
@ -9810,6 +9757,13 @@ static struct ast_cli_entry cli_iax2[] = {
#endif /* IAXTESTS */
};
static void thread_free(struct iax2_thread *thread)
{
ast_mutex_destroy(&thread->lock);
ast_cond_destroy(&thread->cond);
free(thread);
}
static int __unload_module(void)
{
pthread_t threadid = AST_PTHREADT_NULL;
@ -9824,7 +9778,6 @@ static int __unload_module(void)
if (schedthreadid != AST_PTHREADT_NULL) {
pthread_cancel(schedthreadid);
ast_mutex_lock(&sched_lock);
sched_halt = 1;
ast_cond_signal(&sched_cond);
ast_mutex_unlock(&sched_lock);
pthread_join(schedthreadid, NULL);
@ -9835,9 +9788,10 @@ static int __unload_module(void)
AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
AST_LIST_REMOVE_CURRENT(&idle_list, list);
threadid = thread->threadid;
thread->halt = 1;
pthread_cancel(threadid);
signal_condition(&thread->lock, &thread->cond);
pthread_join(threadid, NULL);
thread_free(thread);
}
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_UNLOCK(&idle_list);
@ -9846,23 +9800,25 @@ static int __unload_module(void)
AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
AST_LIST_REMOVE_CURRENT(&active_list, list);
threadid = thread->threadid;
thread->halt = 1;
pthread_cancel(threadid);
signal_condition(&thread->lock, &thread->cond);
pthread_join(threadid, NULL);
thread_free(thread);
}
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_UNLOCK(&active_list);
AST_LIST_LOCK(&dynamic_list);
AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
threadid = thread->threadid;
thread->halt = 1;
signal_condition(&thread->lock, &thread->cond);
pthread_cancel(threadid);
signal_condition(&thread->lock, &thread->cond);
pthread_join(threadid, NULL);
}
thread_free(thread);
}
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_UNLOCK(&dynamic_list);
AST_LIST_UNLOCK(&dynamic_list);
ast_netsock_release(netsock);
for (x=0;x<IAX_MAX_CALLS;x++)
@ -9882,7 +9838,6 @@ static int __unload_module(void)
static int unload_module(void)
{
ast_mutex_destroy(&waresl.lock);
ast_custom_function_unregister(&iaxpeer_function);
return __unload_module();
}
@ -9936,8 +9891,6 @@ static int load_module(void)
}
ast_netsock_init(netsock);
ast_mutex_init(&waresl.lock);
ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));

Loading…
Cancel
Save