dect
/
asterisk
Archived
13
0
Fork 0

Bug 6387 - janitor cleanup for linked lists

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@9349 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
tilghman 2006-02-10 00:20:43 +00:00
parent 105c194a62
commit 45d876ed93
1 changed files with 28 additions and 50 deletions

View File

@ -69,9 +69,6 @@ AST_MUTEX_DEFINE_STATIC(usecnt_lock);
#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
/* Protect the interface list (of sip_pvt's) */
AST_MUTEX_DEFINE_STATIC(locallock);
static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
static int local_digit(struct ast_channel *ast, char digit);
static int local_call(struct ast_channel *ast, char *dest, int timeout);
@ -101,7 +98,7 @@ static const struct ast_channel_tech local_tech = {
.send_html = local_sendhtml,
};
static struct local_pvt {
struct local_pvt {
ast_mutex_t lock; /* Channel private lock */
char context[AST_MAX_CONTEXT]; /* Context to call */
char exten[AST_MAX_EXTENSION]; /* Extension to call */
@ -113,8 +110,10 @@ static struct local_pvt {
int nooptimization; /* Don't leave masq state */
struct ast_channel *owner; /* Master Channel */
struct ast_channel *chan; /* Outbound channel */
struct local_pvt *next; /* Next entity */
} *locals = NULL;
AST_LIST_ENTRY(local_pvt) list; /* Next entity */
};
static AST_LIST_HEAD_STATIC(locals, local_pvt);
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
{
@ -357,23 +356,19 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout)
#if 0
static void local_destroy(struct local_pvt *p)
{
struct local_pvt *cur, *prev = NULL;
ast_mutex_lock(&locallock);
cur = locals;
while(cur) {
struct local_pvt *cur;
AST_LIST_LOCK(&locals);
AST_LIST_TRAVERSE_SAFE_BEGIN(&locals, cur, list) {
if (cur == p) {
if (prev)
prev->next = cur->next;
else
locals = cur->next;
ast_mutex_destroy(cur);
AST_LIST_REMOVE_CURRENT(&locals, list);
ast_mutex_destroy(&cur->lock);
free(cur);
break;
}
prev = cur;
cur = cur->next;
}
ast_mutex_unlock(&locallock);
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_UNLOCK(&locals);
if (!cur)
ast_log(LOG_WARNING, "Unable ot find local '%s@%s' in local list\n", p->exten, p->context);
}
@ -385,7 +380,6 @@ static int local_hangup(struct ast_channel *ast)
struct local_pvt *p = ast->tech_pvt;
int isoutbound;
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
struct local_pvt *cur, *prev=NULL;
struct ast_channel *ochan = NULL;
int glaredetect;
const char *status;
@ -415,20 +409,9 @@ static int local_hangup(struct ast_channel *ast)
p->cancelqueue = 1;
ast_mutex_unlock(&p->lock);
/* Remove from list */
ast_mutex_lock(&locallock);
cur = locals;
while(cur) {
if (cur == p) {
if (prev)
prev->next = cur->next;
else
locals = cur->next;
break;
}
prev = cur;
cur = cur->next;
}
ast_mutex_unlock(&locallock);
AST_LIST_LOCK(&locals);
AST_LIST_REMOVE(&locals, p, list);
AST_LIST_UNLOCK(&locals);
/* Grab / release lock just in case */
ast_mutex_lock(&p->lock);
ast_mutex_unlock(&p->lock);
@ -484,10 +467,9 @@ static struct local_pvt *local_alloc(char *data, int format)
tmp = NULL;
} else {
/* Add to list */
ast_mutex_lock(&locallock);
tmp->next = locals;
locals = tmp;
ast_mutex_unlock(&locallock);
AST_LIST_LOCK(&locals);
AST_LIST_INSERT_HEAD(&locals, tmp, list);
AST_LIST_UNLOCK(&locals);
}
return tmp;
@ -563,17 +545,15 @@ static int locals_show(int fd, int argc, char **argv)
if (argc != 3)
return RESULT_SHOWUSAGE;
ast_mutex_lock(&locallock);
p = locals;
while(p) {
if (AST_LIST_EMPTY(&locals))
ast_cli(fd, "No local channels in use\n");
AST_LIST_LOCK(&locals);
AST_LIST_TRAVERSE(&locals, p, list) {
ast_mutex_lock(&p->lock);
ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
ast_mutex_unlock(&p->lock);
p = p->next;
}
if (!locals)
ast_cli(fd, "No local channels in use\n");
ast_mutex_unlock(&locallock);
AST_LIST_UNLOCK(&locals);
return RESULT_SUCCESS;
}
@ -611,16 +591,14 @@ int unload_module()
/* First, take us out of the channel loop */
ast_cli_unregister(&cli_show_locals);
ast_channel_unregister(&local_tech);
if (!ast_mutex_lock(&locallock)) {
if (!AST_LIST_LOCK(&locals)) {
/* Hangup all interfaces if they have an owner */
p = locals;
while(p) {
AST_LIST_TRAVERSE(&locals, p, list) {
if (p->owner)
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
p = p->next;
}
locals = NULL;
ast_mutex_unlock(&locallock);
AST_LIST_UNLOCK(&locals);
AST_LIST_HEAD_DESTROY(&locals);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;