Index: channel.c =================================================================== --- channel.c (revision 8529) +++ channel.c (working copy) @@ -109,11 +109,8 @@ static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist); /*! the list of channels we have */ -static struct ast_channel *channels = NULL; +static AST_LIST_HEAD_STATIC(channels, ast_channel); -/*! Protect the channel list, both backends and channels. */ -AST_MUTEX_DEFINE_STATIC(chlock); - /*! map AST_CAUSE's to readable string representations */ const struct ast_cause { int cause; @@ -174,7 +171,7 @@ ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); - if (ast_mutex_lock(&chlock)) { + if (AST_LIST_LOCK(&channels)) { ast_log(LOG_WARNING, "Unable to lock channel list\n"); return -1; } @@ -185,7 +182,7 @@ (cl->tech->transfer) ? "yes" : "no"); count_chan++; } - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan); return RESULT_SUCCESS; @@ -200,7 +197,7 @@ if (argc != 3) return RESULT_SHOWUSAGE; - if (ast_mutex_lock(&chlock)) { + if (AST_LIST_LOCK(&channels)) { ast_log(LOG_WARNING, "Unable to lock channel list\n"); return RESULT_FAILURE; } @@ -214,7 +211,7 @@ if (!cl) { ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return RESULT_FAILURE; } @@ -240,7 +237,7 @@ ); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return RESULT_SUCCESS; } @@ -317,10 +314,10 @@ struct ast_channel *c; shutting_down = 1; if (hangup) { - ast_mutex_lock(&chlock); - for (c = channels; c; c = c->next) + AST_LIST_LOCK(&channels); + AST_LIST_TRAVERSE(&channels, c, list) ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); } } @@ -329,10 +326,10 @@ { struct ast_channel *c; int cnt = 0; - ast_mutex_lock(&chlock); - for (c = channels; c; c = c->next) + AST_LIST_LOCK(&channels); + AST_LIST_TRAVERSE(&channels, c, list) cnt++; - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return cnt; } @@ -393,12 +390,12 @@ { struct chanlist *chan; - ast_mutex_lock(&chlock); + AST_LIST_LOCK(&channels); AST_LIST_TRAVERSE(&backends, chan, list) { if (!strcasecmp(tech->type, chan->tech->type)) { ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return -1; } } @@ -406,7 +403,7 @@ chan = malloc(sizeof(*chan)); if (!chan) { ast_log(LOG_WARNING, "Out of memory\n"); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return -1; } chan->tech = tech; @@ -419,7 +416,7 @@ ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return 0; } @@ -430,7 +427,7 @@ if (option_debug) ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); - ast_mutex_lock(&chlock); + AST_LIST_LOCK(&channels); AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { if (chan->tech == tech) { @@ -443,7 +440,7 @@ } AST_LIST_TRAVERSE_SAFE_END - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); } const struct ast_channel_tech *ast_get_channel_tech(const char *name) @@ -451,7 +448,7 @@ struct chanlist *chanls; const struct ast_channel_tech *ret = NULL; - if (ast_mutex_lock(&chlock)) { + if (AST_LIST_LOCK(&channels)) { ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); return NULL; } @@ -463,7 +460,7 @@ } } - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return ret; } @@ -664,11 +661,9 @@ tmp->tech = &null_tech; - ast_mutex_lock(&chlock); - tmp->next = channels; - channels = tmp; - - ast_mutex_unlock(&chlock); + AST_LIST_LOCK(&channels); + AST_LIST_INSERT_HEAD(&channels, tmp, list); + AST_LIST_UNLOCK(&channels); return tmp; } @@ -801,8 +796,8 @@ struct ast_channel *c; for (retries = 0; retries < 10; retries++) { - ast_mutex_lock(&chlock); - for (c = channels; c; c = c->next) { + AST_LIST_LOCK(&channels); + AST_LIST_TRAVERSE(&channels, c, list) { if (!prev) { /* want head of list */ if (!name && !exten) @@ -831,7 +826,7 @@ break; } } else if (c == prev) { /* found, return c->next */ - c = c->next; + c = AST_LIST_NEXT(c, list); break; } } @@ -840,7 +835,7 @@ /* this is slightly unsafe, as we _should_ hold the lock to access c->name */ if (!done && c) ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); if (done) return c; usleep(1); @@ -929,7 +924,6 @@ /*! \brief Free a channel structure */ void ast_channel_free(struct ast_channel *chan) { - struct ast_channel *last=NULL, *cur; int fd; struct ast_var_t *vardata; struct ast_frame *f, *fp; @@ -938,25 +932,12 @@ headp=&chan->varshead; - ast_mutex_lock(&chlock); - for (cur = channels; cur; cur = cur->next) { - if (cur == chan) { - if (last) - last->next = cur->next; - else - channels = cur->next; - break; - } - last = cur; - } - 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); - } + AST_LIST_LOCK(&channels); + AST_LIST_REMOVE(&channels, chan, list); + /* Lock and unlock the channel just to be sure nobody + has it locked still */ + ast_mutex_lock(&chan->lock); + ast_mutex_unlock(&chan->lock); if (chan->tech_pvt) { ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); free(chan->tech_pvt); @@ -1007,7 +988,7 @@ ast_var_delete(vardata); free(chan); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); ast_device_state_changed_literal(name); } @@ -2564,7 +2545,7 @@ cause = &foo; *cause = AST_CAUSE_NOTDEFINED; - if (ast_mutex_lock(&chlock)) { + if (AST_LIST_LOCK(&channels)) { ast_log(LOG_WARNING, "Unable to lock channel list\n"); return NULL; } @@ -2578,10 +2559,10 @@ res = ast_translator_best_choice(&fmt, &capabilities); if (res < 0) { ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return NULL; } - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); if (!chan->tech->requester) return NULL; @@ -2605,7 +2586,7 @@ ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); *cause = AST_CAUSE_NOSUCHDRIVER; - ast_mutex_unlock(&chlock); + AST_LIST_UNLOCK(&channels); return NULL; } Index: include/asterisk/channel.h =================================================================== --- include/asterisk/channel.h (revision 8529) +++ include/asterisk/channel.h (working copy) @@ -411,7 +411,7 @@ struct ast_channel_spy_list *spies; /*! For easy linking */ - struct ast_channel *next; + AST_LIST_ENTRY(ast_channel) list; }; /* \defgroup chanprop Channel tech properties: