/*! \brief the list of channels we have. Note that the lock for this list is used for
both the channels list and the backends list. */
-static AST_LIST_HEAD_STATIC(channels, ast_channel);
+static AST_RWLIST_HEAD_STATIC(channels, ast_channel);
/*! \brief map AST_CAUSE's to readable string representations
*
ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer");
ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
- if (AST_LIST_LOCK(&channels)) {
+ if (AST_RWLIST_RDLOCK(&channels)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n");
return -1;
}
(cl->tech->transfer) ? "yes" : "no");
count_chan++;
}
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
return RESULT_SUCCESS;
if (argc != 4)
return RESULT_SHOWUSAGE;
- if (AST_LIST_LOCK(&channels)) {
+ if (AST_RWLIST_RDLOCK(&channels)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n");
return RESULT_FAILURE;
}
if (!cl) {
ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return RESULT_FAILURE;
}
);
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return RESULT_SUCCESS;
}
struct ast_channel *c;
shutting_down = 1;
if (hangup) {
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list)
+ AST_RWLIST_RDLOCK(&channels);
+ AST_RWLIST_TRAVERSE(&channels, c, chan_list)
ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
}
}
{
struct ast_channel *c;
int cnt = 0;
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list)
+ AST_RWLIST_RDLOCK(&channels);
+ AST_RWLIST_TRAVERSE(&channels, c, chan_list)
cnt++;
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return cnt;
}
{
struct chanlist *chan;
- AST_LIST_LOCK(&channels);
+ AST_RWLIST_WRLOCK(&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_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return -1;
}
}
if (!(chan = ast_calloc(1, sizeof(*chan)))) {
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return -1;
}
chan->tech = tech;
ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
chan->tech->description);
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return 0;
}
if (option_debug)
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
- AST_LIST_LOCK(&channels);
+ AST_RWLIST_WRLOCK(&channels);
AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
if (chan->tech == tech) {
}
AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
}
/*! \brief Get handle to channel driver based on name */
struct chanlist *chanls;
const struct ast_channel_tech *ret = NULL;
- if (AST_LIST_LOCK(&channels)) {
+ if (AST_RWLIST_RDLOCK(&channels)) {
ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
return NULL;
}
}
}
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return ret;
}
tmp->tech = &null_tech;
- AST_LIST_LOCK(&channels);
- AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_WRLOCK(&channels);
+ AST_RWLIST_INSERT_HEAD(&channels, tmp, chan_list);
+ AST_RWLIST_UNLOCK(&channels);
return tmp;
}
for (retries = 0; retries < 10; retries++) {
int done;
- AST_LIST_LOCK(&channels);
- AST_LIST_TRAVERSE(&channels, c, chan_list) {
+ AST_RWLIST_RDLOCK(&channels);
+ AST_RWLIST_TRAVERSE(&channels, c, chan_list) {
if (prev) { /* look for next item */
if (c != prev) /* not this one */
continue;
/* found, prepare to return c->next */
- if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break;
+ if ((c = AST_RWLIST_NEXT(c, chan_list)) == NULL) break;
/* If prev was the last item on the channel list, then we just
* want to return NULL, instead of trying to deref NULL in the
* next section.
}
}
}
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
if (done)
return c;
usleep(1); /* give other threads a chance before retrying */
headp=&chan->varshead;
- AST_LIST_LOCK(&channels);
- if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_WRLOCK(&channels);
+ if (!AST_RWLIST_REMOVE(&channels, chan, chan_list)) {
+ AST_RWLIST_UNLOCK(&channels);
ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
}
/* Lock and unlock the channel just to be sure nobody
ast_string_field_free_pools(chan);
ast_free(chan);
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
ast_device_state_changed_literal(name);
}
cause = &foo;
*cause = AST_CAUSE_NOTDEFINED;
- if (AST_LIST_LOCK(&channels)) {
+ if (AST_RWLIST_RDLOCK(&channels)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n");
return NULL;
}
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);
*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return NULL;
}
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
if (!chan->tech->requester)
return NULL;
ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
*cause = AST_CAUSE_NOSUCHDRIVER;
- AST_LIST_UNLOCK(&channels);
+ AST_RWLIST_UNLOCK(&channels);
return NULL;
}