- add AST_LIST_HEAD_NOLOCK_STATIC, similar to AST_LIST_HEAD_STATIC, but without the lock!

- store registered channel backends using linked list macros


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7968 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Russell Bryant 20 years ago
parent e0d4fcfb55
commit 752e3c8938

@ -102,11 +102,11 @@ unsigned long global_fin = 0, global_fout = 0;
struct chanlist { struct chanlist {
const struct ast_channel_tech *tech; const struct ast_channel_tech *tech;
struct chanlist *next; AST_LIST_ENTRY(chanlist) list;
}; };
/*! the list of registered channel types */ /*! the list of registered channel types */
static struct chanlist *backends = NULL; static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
/*! the list of channels we have */ /*! the list of channels we have */
static struct ast_channel *channels = NULL; static struct ast_channel *channels = NULL;
@ -178,7 +178,7 @@ static int show_channeltypes(int fd, int argc, char *argv[])
ast_log(LOG_WARNING, "Unable to lock channel list\n"); ast_log(LOG_WARNING, "Unable to lock channel list\n");
return -1; return -1;
} }
for (cl = backends; cl; cl = cl->next) { AST_LIST_TRAVERSE(&backends, cl, list) {
ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description, ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
(cl->tech->devicestate) ? "yes" : "no", (cl->tech->devicestate) ? "yes" : "no",
(cl->tech->indicate) ? "yes" : "no", (cl->tech->indicate) ? "yes" : "no",
@ -315,7 +315,7 @@ int ast_channel_register(const struct ast_channel_tech *tech)
ast_mutex_lock(&chlock); ast_mutex_lock(&chlock);
for (chan = backends; chan; chan = chan->next) { AST_LIST_TRAVERSE(&backends, chan, list) {
if (!strcasecmp(tech->type, chan->tech->type)) { if (!strcasecmp(tech->type, chan->tech->type)) {
ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
ast_mutex_unlock(&chlock); ast_mutex_unlock(&chlock);
@ -329,9 +329,7 @@ int ast_channel_register(const struct ast_channel_tech *tech)
ast_mutex_unlock(&chlock); ast_mutex_unlock(&chlock);
return -1; return -1;
} }
chan->tech = tech; AST_LIST_INSERT_HEAD(&backends, chan, list);
chan->next = backends;
backends = chan;
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
@ -346,29 +344,23 @@ int ast_channel_register(const struct ast_channel_tech *tech)
void ast_channel_unregister(const struct ast_channel_tech *tech) void ast_channel_unregister(const struct ast_channel_tech *tech)
{ {
struct chanlist *chan, *last=NULL; struct chanlist *chan;
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
ast_mutex_lock(&chlock); ast_mutex_lock(&chlock);
for (chan = backends; chan; chan = chan->next) { AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
if (chan->tech == tech) { if (chan->tech == tech) {
if (last) AST_LIST_REMOVE_CURRENT(&backends, list);
last->next = chan->next;
else
backends = backends->next;
free(chan); free(chan);
ast_mutex_unlock(&chlock);
if (option_verbose > 1) if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type); ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
break;
return;
} }
last = chan;
} }
AST_LIST_TRAVERSE_SAFE_END
ast_mutex_unlock(&chlock); ast_mutex_unlock(&chlock);
} }
@ -376,22 +368,23 @@ void ast_channel_unregister(const struct ast_channel_tech *tech)
const struct ast_channel_tech *ast_get_channel_tech(const char *name) const struct ast_channel_tech *ast_get_channel_tech(const char *name)
{ {
struct chanlist *chanls; struct chanlist *chanls;
const struct ast_channel_tech *ret = NULL;
if (ast_mutex_lock(&chlock)) { if (ast_mutex_lock(&chlock)) {
ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
return NULL; return NULL;
} }
for (chanls = backends; chanls; chanls = chanls->next) { AST_LIST_TRAVERSE(&backends, chanls, list) {
if (strcasecmp(name, chanls->tech->type)) if (!strcasecmp(name, chanls->tech->type)) {
continue; ret = chanls->tech;
break;
ast_mutex_unlock(&chlock); }
return chanls->tech;
} }
ast_mutex_unlock(&chlock); ast_mutex_unlock(&chlock);
return NULL;
return ret;
} }
/*! \brief Gives the string form of a given hangup cause */ /*! \brief Gives the string form of a given hangup cause */
@ -2491,7 +2484,7 @@ struct ast_channel *ast_request(const char *type, int format, void *data, int *c
return NULL; return NULL;
} }
for (chan = backends; chan; chan = chan->next) { AST_LIST_TRAVERSE(&backends, chan, list) {
if (strcasecmp(type, chan->tech->type)) if (strcasecmp(type, chan->tech->type))
continue; continue;

@ -128,6 +128,20 @@ struct name { \
.lock = AST_MUTEX_INIT_VALUE, \ .lock = AST_MUTEX_INIT_VALUE, \
}; };
/*!
\brief Defines a structure to be used to hold a list of specified type, statically initialized.
This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
*/
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
struct name { \
struct type *first; \
struct type *last; \
} name = { \
.first = NULL, \
.last = NULL, \
};
/*! /*!
\brief Initializes a list head structure with a specified first entry. \brief Initializes a list head structure with a specified first entry.
\param head This is a pointer to the list head structure \param head This is a pointer to the list head structure

Loading…
Cancel
Save